#include <u.h>#include <libc.h>#include <draw.h>#include <event.h>#include "game.h" /* Traditional dimensions in tenth of mm */enum{ Gobanw = 4242, Gobanh = 4545, Line = 10, Linew = 220, Lineh = 237, Hoshidiam = 40, Stonediam = 225}; enum{ DGoban = 0xD79C5EFF}; static Point ogoban; /* Origin of the lines of the goban. */static double scale; intdrawgoban(void){ int i, j; int l, hr, sr; char s[Maxgobansize]; /* Just need a length */ int hoshi[3]; Point o; Point p, q; Rectangle r; Point poly[4]; Image *bg; Font *font; o = screen->r.min; if(Dx(screen->r) * Gobanh < Dy(screen->r) * Gobanw){ scale = (double)Dx(screen->r) / Gobanw; }else{ scale = (double)Dy(screen->r) / Gobanh; } /* The line function uses 1 + 2 * width as its thickness. */ l = (Line * scale - 1) / 2; /* Fill goban background. */ p = Pt(o.x + (int)(scale * Gobanw), o.y + (int)(scale * Gobanh)); r = Rpt(o, p); poly[0] = r.min; poly[1] = Pt(r.max.x, r.min.y); poly[2] = r.max; poly[3] = Pt(r.min.x, r.max.y); bg = allocimage(display, Rect(0, 0, 1, 1), RGB24, 1, DGoban); fillpoly(screen, poly, 4, ~0, bg, ZP); freeimage(bg); /* Draw lines. */ ogoban = Pt(o.x + scale * (Gobanw - (sgoban - 1) * Linew) / 2, o.y + scale * (Gobanh - (sgoban - 1) * Lineh) / 2); for(i = 0; i < sgoban; i++){ p = Pt(ogoban.x + (int)(i * scale * Linew), ogoban.y); q = Pt(ogoban.x + (int)(i * scale * Linew), ogoban.y + (int)(scale * (sgoban - 1) * Lineh)); line(screen, p, q, Enddisc, Enddisc, l / 2, display->black, ZP); p = Pt(ogoban.x, ogoban.y + (int)(i * scale * Lineh)); q = Pt(ogoban.x + (int)(scale * (sgoban - 1) * Linew), ogoban.y + (int)(i * scale * Lineh)); line(screen, p, q, Enddisc, Enddisc, l / 2, display->black, ZP); } /* Draw hoshi; only meaningful for 19x19, 13x13 and 9x9. */ hr = scale * Hoshidiam / 2; switch(sgoban){ case 19: hoshi[0] = 3; hoshi[1] = 9; hoshi[2] = 15; break; case 13: hoshi[0] = 3; hoshi[1] = 6; hoshi[2] = 9; break; case 9: hoshi[0] = 2; hoshi[1] = 4; hoshi[2] = 6; break; default: hoshi[0] = 0; } for(i = 0; i < 3 && hoshi[0] != 0; i++){ for(j = 0; j < 3; j++){ p = Pt(ogoban.x + (int)(hoshi[i] * scale * Linew), ogoban.y + (int)(hoshi[j] * scale * Lineh)); fillellipse(screen, p, hr, hr, display->black, ZP); } } /* Draw stones. */ sr = scale * Stonediam / 2; for(i = 0; i < sgoban * sgoban; i++){ switch(goban[i]){ case Black: p = Pt(ogoban.x + i % sgoban * scale * Linew, ogoban.y + i / sgoban * scale * Lineh); fillellipse(screen, p, sr, sr, display->black, ZP); break; case White: p = Pt(ogoban.x + i % sgoban * scale * Linew, ogoban.y + i / sgoban * scale * Lineh); ellipse(screen, p, sr, sr, 0, display->black, ZP); fillellipse(screen, p, sr-1, sr-1, display->white, ZP); break; } } /* Draw text: turn, prisonners, later on byo-yomi & time. */ if((font = openfont(display, "/lib/font/bit/dejavu/unicode.18.font")) == nil){ werrstr("Could not open font."); return -1; } p = addpt(o, Pt(ogoban.x - o.x, scale * (Gobanh + Lineh))); sprint(s, "To play: %s", turn == Black ? "Black " : "White "); stringbg(screen, p, display->black, ZP, font, s, display->white, ZP); p = addpt(p, Pt(0, font->height)); sprint(s, "Black prisonners: %d", nblackcaptured); stringbg(screen, p, display->black, ZP, font, s, display->white, ZP); p = addpt(p, Pt(0, font->height)); sprint(s, "White prisonners: %d", nwhitecaptured); stringbg(screen, p, display->black, ZP, font, s, display->white, ZP); return 0;} /* Pixel coordinates to Go move. */intpx2move(Point px){ Point p; Rectangle r; p = Pt(ogoban.x - scale * Linew / 2, ogoban.y - scale * Lineh / 2); r = Rect(p.x, p.y, p.x + scale * sgoban * Linew, p.y + scale * sgoban * Lineh); if(ptinrect(px, r) == 0){ werrstr("Click out of the goban."); return -1; } p = subpt(px, r.min); p.x /= scale * Linew; p.y /= scale * Lineh; return p.y * sgoban + p.x;}
#include <u.h>
#include <libc.h>
#include <draw.h>
#include <event.h>
#include "game.h"
/* Traditional dimensions in tenth of mm */
enum{
Gobanw = 4242,
Gobanh = 4545,
Line = 10,
Linew = 220,
Lineh = 237,
Hoshidiam = 40,
Stonediam = 225
};
enum{
DGoban = 0xD79C5EFF
};
static Point ogoban; /* Origin of the lines of the goban. */
static double scale;
int
drawgoban(void)
{
int i, j;
int l, hr, sr;
char s[Maxgobansize]; /* Just need a length */
int hoshi[3];
Point o;
Point p, q;
Rectangle r;
Point poly[4];
Image *bg;
Font *font;
o = screen->r.min;
if(Dx(screen->r) * Gobanh < Dy(screen->r) * Gobanw){
scale = (double)Dx(screen->r) / Gobanw;
}else{
scale = (double)Dy(screen->r) / Gobanh;
}
/* The line function uses 1 + 2 * width as its thickness. */
l = (Line * scale - 1) / 2;
/* Fill goban background. */
p = Pt(o.x + (int)(scale * Gobanw), o.y + (int)(scale * Gobanh));
r = Rpt(o, p);
poly[0] = r.min;
poly[1] = Pt(r.max.x, r.min.y);
poly[2] = r.max;
poly[3] = Pt(r.min.x, r.max.y);
bg = allocimage(display, Rect(0, 0, 1, 1), RGB24, 1, DGoban);
fillpoly(screen, poly, 4, ~0, bg, ZP);
freeimage(bg);
/* Draw lines. */
ogoban = Pt(o.x + scale * (Gobanw - (sgoban - 1) * Linew) / 2,
o.y + scale * (Gobanh - (sgoban - 1) * Lineh) / 2);
for(i = 0; i < sgoban; i++){
p = Pt(ogoban.x + (int)(i * scale * Linew), ogoban.y);
q = Pt(ogoban.x + (int)(i * scale * Linew),
ogoban.y + (int)(scale * (sgoban - 1) * Lineh));
line(screen, p, q, Enddisc, Enddisc, l / 2, display->black, ZP);
p = Pt(ogoban.x, ogoban.y + (int)(i * scale * Lineh));
q = Pt(ogoban.x + (int)(scale * (sgoban - 1) * Linew),
ogoban.y + (int)(i * scale * Lineh));
line(screen, p, q, Enddisc, Enddisc, l / 2, display->black, ZP);
}
/* Draw hoshi; only meaningful for 19x19, 13x13 and 9x9. */
hr = scale * Hoshidiam / 2;
switch(sgoban){
case 19:
hoshi[0] = 3;
hoshi[1] = 9;
hoshi[2] = 15;
break;
case 13:
hoshi[0] = 3;
hoshi[1] = 6;
hoshi[2] = 9;
break;
case 9:
hoshi[0] = 2;
hoshi[1] = 4;
hoshi[2] = 6;
break;
default:
hoshi[0] = 0;
}
for(i = 0; i < 3 && hoshi[0] != 0; i++){
for(j = 0; j < 3; j++){
p = Pt(ogoban.x + (int)(hoshi[i] * scale * Linew),
ogoban.y + (int)(hoshi[j] * scale * Lineh));
fillellipse(screen, p, hr, hr, display->black, ZP);
}
}
/* Draw stones. */
sr = scale * Stonediam / 2;
for(i = 0; i < sgoban * sgoban; i++){
switch(goban[i]){
case Black:
p = Pt(ogoban.x + i % sgoban * scale * Linew,
ogoban.y + i / sgoban * scale * Lineh);
fillellipse(screen, p, sr, sr, display->black, ZP);
break;
case White:
p = Pt(ogoban.x + i % sgoban * scale * Linew,
ogoban.y + i / sgoban * scale * Lineh);
ellipse(screen, p, sr, sr, 0, display->black, ZP);
fillellipse(screen, p, sr-1, sr-1, display->white, ZP);
break;
}
}
/* Draw text: turn, prisonners, later on byo-yomi & time. */
if((font = openfont(display, "/lib/font/bit/dejavu/unicode.18.font")) == nil){
werrstr("Could not open font.");
return -1;
}
p = addpt(o, Pt(ogoban.x - o.x, scale * (Gobanh + Lineh)));
sprint(s, "To play: %s", turn == Black ? "Black " : "White ");
stringbg(screen, p, display->black, ZP, font, s, display->white, ZP);
p = addpt(p, Pt(0, font->height));
sprint(s, "Black prisonners: %d", nblackcaptured);
stringbg(screen, p, display->black, ZP, font, s, display->white, ZP);
p = addpt(p, Pt(0, font->height));
sprint(s, "White prisonners: %d", nwhitecaptured);
stringbg(screen, p, display->black, ZP, font, s, display->white, ZP);
return 0;
}
/* Pixel coordinates to Go move. */
int
px2move(Point px)
{
Point p;
Rectangle r;
p = Pt(ogoban.x - scale * Linew / 2, ogoban.y - scale * Lineh / 2);
r = Rect(p.x, p.y, p.x + scale * sgoban * Linew,
p.y + scale * sgoban * Lineh);
if(ptinrect(px, r) == 0){
werrstr("Click out of the goban.");
return -1;
}
p = subpt(px, r.min);
p.x /= scale * Linew;
p.y /= scale * Lineh;
return p.y * sgoban + p.x;
}