aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bts.c63
-rw-r--r--btsd.c10
-rw-r--r--fns.h1
-rw-r--r--util.c13
4 files changed, 79 insertions, 8 deletions
diff --git a/bts.c b/bts.c
index 7360d0b..26592ee 100644
--- a/bts.c
+++ b/bts.c
@@ -28,6 +28,11 @@ struct {
int state;
} game;
+struct {
+ Image *c; /* color */
+ char *s; /* banner text */
+} conclusion;
+
Point
fromworld(Point2 p)
@@ -167,7 +172,7 @@ drawinfo(Image *dst)
if(s == nil)
return;
p = Pt(SCRW/2 - stringwidth(font, s)/2, SCRH-Boardmargin);
- stringbg(dst, p, display->white, ZP, font, s, display->black, ZP);
+ string(dst, p, display->white, ZP, font, s);
}
void
@@ -181,22 +186,40 @@ redraw(void)
drawships(screenb);
drawinfo(screenb);
+ if(conclusion.s != nil)
+ string(screenb, Pt(SCRW/2 - stringwidth(font, conclusion.s)/2, 0), conclusion.c, ZP, font, conclusion.s);
+
draw(screen, screen->r, screenb, nil, ZP);
flushimage(display, 1);
unlockdisplay(display);
+
+ if(conclusion.s != nil){
+ sleep(5000);
+ conclusion.s = nil;
+ redraw();
+ }
}
void
resize(void)
{
+ int fd;
+
lockdisplay(display);
if(getwindow(display, Refnone) < 0)
sysfatal("resize failed");
unlockdisplay(display);
- freeimage(screenb);
- screenb = eallocimage(display, rectsubpt(screen->r, screen->r.min), screen->chan, 0, DNofill);
+ /* ignore move events */
+ if(Dx(screen->r) != SCRW || Dy(screen->r) != SCRH){
+ fd = open("/dev/wctl", OWRITE);
+ if(fd >= 0){
+ fprint(fd, "resize %s", winspec);
+ close(fd);
+ }
+ }
+
send(drawchan, nil);
}
@@ -354,7 +377,7 @@ lmb(Mousectl *mc)
switch(game.state){
case Outlaying:
if(b == &localboard)
- if(curship != nil)
+ if(curship != nil && rectinrect(curship->bbox, localboard.bbox))
if(++curship-armada >= nelem(armada))
curship = nil;
else if(curship != &armada[0])
@@ -405,7 +428,9 @@ mmb(Mousectl *mc)
break;
}
curship->p = toboard(&localboard, curship->bbox.min);
- /* TODO check for collision with other ships */
+
+ if(rectXarmada(curship->bbox))
+ curship->bbox = ZR;
}
break;
}
@@ -536,6 +561,30 @@ inputthread(void *arg)
}
void
+celebrate(void)
+{
+ static Image *c;
+ static char s[] = "YOU WON!";
+
+ if(c == nil)
+ c = eallocimage(display, Rect(0,0,1,1), screen->chan, 1, DGreen);
+ conclusion.c = c;
+ conclusion.s = s;
+}
+
+void
+keelhaul(void)
+{
+ static Image *c;
+ static char s[] = "…YOU LOST";
+
+ if(c == nil)
+ c = eallocimage(display, Rect(0,0,1,1), screen->chan, 1, DRed);
+ conclusion.c = c;
+ conclusion.s = s;
+}
+
+void
processcmd(char *cmd)
{
Point2 cell;
@@ -545,11 +594,11 @@ processcmd(char *cmd)
fprint(2, "rcvd '%s'\n", cmd);
if(strcmp(cmd, "win") == 0){
-// celebrate();
+ celebrate();
resetgame();
game.state = Waiting0;
}else if(strcmp(cmd, "lose") == 0){
-// keelhaul();
+ keelhaul();
resetgame();
game.state = Waiting0;
}
diff --git a/btsd.c b/btsd.c
index 54719e3..92346b2 100644
--- a/btsd.c
+++ b/btsd.c
@@ -179,6 +179,13 @@ serveproc(void *arg)
settile(op, cell, Thit);
write(p->fd, "hit\n", 4);
fprint(op->fd, "hit %s\n", cell2coords(cell));
+ if(countshipcells(op) < 1){
+ write(p->fd, "win\n", 4);
+ write(op->fd, "lose\n", 5);
+ pushplayer(p);
+ pushplayer(op);
+ goto Finish;
+ }
goto Swapturn;
case Twater:
settile(op, cell, Tmiss);
@@ -192,12 +199,13 @@ Swapturn:
break;
}
if(debug)
- fprint(2, "%d waits, %d plays\n", i, i^1);
+ fprint(2, "%d plays, %d waits\n", i^1, i);
}
break;
}
free(s);
}
+Finish:
if(debug)
fprint(2, "[%d] serveproc ending\n", getpid());
free(m);
diff --git a/fns.h b/fns.h
index 1a9203f..cea6e73 100644
--- a/fns.h
+++ b/fns.h
@@ -16,4 +16,5 @@ int gettile(Map*, Point2);
void settile(Map*, Point2, int);
void settiles(Map*, Point2, int, int, int);
void fprintmap(int, Map*);
+int countshipcells(Map*);
int shiplen(int);
diff --git a/util.c b/util.c
index 42db012..826a508 100644
--- a/util.c
+++ b/util.c
@@ -94,6 +94,19 @@ fprintmap(int fd, Map *m)
}
int
+countshipcells(Map *m)
+{
+ int i, j, n;
+
+ n = 0;
+ for(i = 0; i < MAPW; i++)
+ for(j = 0; j < MAPH; j++)
+ if(gettile(m, Pt2(i,j,1)) == Tship)
+ n++;
+ return n;
+}
+
+int
shiplen(int stype)
{
assert(stype >= 0 && stype < NSHIPS);