#include <u.h>
#include <libc.h>
#include <thread.h>
#include <draw.h>
#include <igo.h>
#include <chan.h>
int Δx, Δy;
int waskou;
void
drawgoban(void)
{
int i,j;
Point pos;
for (i=0; i<Hcapsz; i++){
pos=hcap[i];
drawstone(pos,'p');
}
for (i=1; i<Bansz+1; i++){
for (j=1; j<Bansz+1; j++){
if(goban[i][j]!='d'){
pos.x=i;
pos.y=j;
drawstone(pos, goban[i][j]);
}
}
}
if(moves)
drawstone(lstone,'l');
}
static void
rmvlabel(void)
{
Rectangle r;
r.min=pul;
r.max.x=fontcorn.x;
r.max.y=pul.y+Δy-Pointsz;
draw(screen, r, pixbg, nil, ZP);
}
void
drwlabel(int bdead, int wdead, int time)
{
Font *defont;
Rune r[40];
rmvlabel();
defont = display->defaultfont;
runesprint(r, "b: %d w: %d time: %d",bdead, wdead,time);
fontcorn=runestring(screen, pul, pixfg, ZP, defont,r);
}
void
redraw(void)
{
int i;
Point pur, pdl, pdr; /* (↑ ↓)^(← →) – corners*/
Point st, end;
pul=Pt(screen->r.min.x,screen->r.min.y);
pdr=Pt(screen->r.max.x,screen->r.max.y);
pur.y=pul.y;
pur.x=pdr.x;
pdl.x=pul.x;
pdl.y=pdr.y;
Δx=abs(pur.x-pul.x)/(Bansz+1);
Δy=abs(pdl.y-pul.y)/(Bansz+1);
draw(screen, screen->r, pixbg, nil, ZP);
for (i=1; i<Bansz+1; i++){
st=Pt(pul.x+i*Δx,pul.y+Δy);
end=Pt(pdl.x+i*Δx,pul.y+Δy*Bansz);
line(screen, st, end, Endsquare, Endsquare,
1, pixfg, Pt(0,0));
st=Pt(pul.x+Δx,pul.y+i*Δy);
end=Pt(pul.x+Δx*Bansz,pur.y+i*Δy);
line(screen, st, end, Endsquare, Endsquare,
1, pixfg, Pt(0,0));
}
drawgoban();
drwlabel(bdead,wdead,clk);
flushimage(display,1);
}
void
initifc(void)
{
bdead=0;
wdead=0;
clk=0;
visible = 1;
cleangoban();
if (initdraw(nil, nil, "goifc") < 0)
exits("initdraw failed");
pixbl = allocimage(display, Rect(0,0,1,1),
screen->chan, 1, DBluegreen);
pixbg = allocimage(display, Rect(0,0,1,1),
screen->chan, 1, DGobrown);
pixfg = allocimage(display, Rect(0,0,1,1),
screen->chan, 1, DBlack);
pixwht = allocimage(display, Rect(0,0,1,1),
screen->chan, 1, DWhite);
pixst = allocimage(display, Rect(0,0,1,1),
screen->chan, 1, DSTbord);
pixko = allocimage(display, Rect(0,0,1,1),
screen->chan, 1, DRed);
pixyell = allocimage(display, Rect(0,0,1,1),
screen->chan, 1, DYellow);
if(!pixbg||!pixfg||!pixwht||!pixst)
exits("out of image memory");
redraw();
}
static int
drawstone(Point pos,char type)
{
Point lpos, st, end;
int xpos, ypos, radx ,rady;
int notup, notleft, notright, notdown;
int i;
if(!visible)
return 0;
xpos = pos.x;
ypos = pos.y;
notright=!(xpos==19);
notleft=!(xpos==1);
notup=!(ypos==19);
notdown=!(ypos==1);
xpos = pul.x+xpos*Δx;
ypos = pul.y+ypos*Δy;
lpos = Pt(xpos, ypos);
radx = Δx/Stonesz;
rady = Δy/Stonesz;
if(type!=Emptystone && type!='p' && type!=Lstone)
drawstone(pos, Emptystone);
switch(type){
case Bstone:
fillellipse(screen, Pt(xpos,ypos), radx, rady,
pixfg, Pt(0,0));
ellipse(screen, Pt(xpos,ypos), radx-1, rady-1, 1,
pixst, Pt(0,0));
break;
case Wstone:
fillellipse(screen, Pt(xpos,ypos), radx, rady,
pixwht, Pt(0,0));
ellipse(screen, Pt(xpos,ypos), radx-1, rady-1, 1,
pixfg, Pt(0,0));
break;
case 't':
dprint("triangle...");
break;
case 'p':
radx = Δx/Pointsz;
rady = Δy/Pointsz;
fillellipse(screen, Pt(xpos,ypos), radx, rady,
pixfg, Pt(0,0));
break;
case Cntstone:
radx = Δx/Countsz;
rady = Δy/Countsz;
fillellipse(screen, Pt(xpos,ypos), radx, rady,
pixbl, Pt(0,0));
break;
case Wmarked:
fillellipse(screen, Pt(xpos,ypos), radx, rady,
pixwht, Pt(0,0));
ellipse(screen, Pt(xpos,ypos), radx-1, rady-1, 1,
pixfg, Pt(0,0));
radx = Δx/Pointsz-1;
rady = Δy/Pointsz-1;
fillellipse(screen, Pt(xpos,ypos), radx, rady,
pixyell, Pt(0,0)); /* yellow & black */
ellipse(screen, Pt(xpos,ypos), radx-1, rady-1, 1,
pixfg, Pt(0,0));
break;
case Bmarked:
fillellipse(screen, Pt(xpos,ypos), radx, rady,
pixfg, Pt(0,0));
ellipse(screen, Pt(xpos,ypos), radx-1, rady-1,
1, pixst, Pt(0,0));
radx = Δx/Pointsz-1;
rady = Δy/Pointsz-1;
fillellipse(screen, Pt(xpos,ypos), radx, rady,
pixyell, Pt(0,0));
break;
case Kou:
radx = Δx/Pointsz;
rady = Δy/Pointsz;
fillellipse(screen, Pt(xpos,ypos), radx, rady,
pixko, Pt(0,0));
break;
case Lstone:
radx = Δx/Countsz-1;
rady = Δy/Countsz-1;
fillellipse(screen, Pt(xpos,ypos), radx, rady,
pixko, Pt(0,0));
break;
case Emptystone:
fillellipse(screen, Pt(xpos,ypos), radx, rady,
pixbg, Pt(0,0));
st=Pt(xpos+notright*radx+1,ypos);
end=Pt(xpos-notleft*radx-1,ypos);
line(screen,st,end, Endsquare, Endsquare, 1,
pixfg, Pt(0,0));
st=Pt(xpos,ypos+notup*rady+1);
end=Pt(xpos,ypos-notdown*rady-1);
line(screen,st,end, Endsquare, Endsquare,1,
pixfg, Pt(0,0));
for(i=0;i<9;i++)
if(pos.x==hcap[i].x && pos.y==hcap[i].y)
drawstone(pos,'p');
break;
default:
sysfatal("drawstone: weird stone: %d", type);
break;
}
return 0;
}
void
opdraw(Move *m, char)
{
drawstone(m->Point, goban[m->x][m->y]);
}
void
ifcthread(void *)
{
Move *mdead, *mv;
int ndead;
mdead=nil;
while(mv=recvp(ifcchan)){
if(moves && visible)
drawstone(lstone, goban[lstone.x][lstone.y]);
if(lkou.type)
waskou++;
ndead=move(mv,&mdead);
dprint("ndead = %d\n", ndead);
if(ndead >= 0 && visible && waskou){
dprint("cleaning\n");
drawstone(lkou, Emptystone);
lkou.type = '\0';
}
waskou = 0;
if(ndead>0){
if(mv->type == Wstone)
wdead+=ndead;
if(mv->type == Bstone)
bdead+=ndead;
if(visible)
drwlabel(bdead,wdead,0);
}
if(ndead>=0){
opdraw(mv, goban[mv->x][mv->y]);
opgrp(mdead, '\0', opdraw);
}
if(ndead>=0 && mv->ev.m && mv->ev.fd)
fprint(mv->ev.fd, "%d,%d\n", mv->x, mv->y);
if(lstone.type)
drawstone(lstone, Lstone);
sendp(ifcchan,mdead);
mdead=nil;
}
}
|