diff options
-rw-r--r-- | bts.c | 63 | ||||
-rw-r--r-- | btsd.c | 10 | ||||
-rw-r--r-- | fns.h | 1 | ||||
-rw-r--r-- | util.c | 13 |
4 files changed, 79 insertions, 8 deletions
@@ -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; } @@ -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); @@ -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); @@ -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); |