]> git.cameronkatri.com Git - bsdgames-darwin.git/commitdiff
import dots+boxes games.
authorchristos <christos@NetBSD.org>
Fri, 26 Dec 2003 17:57:02 +0000 (17:57 +0000)
committerchristos <christos@NetBSD.org>
Fri, 26 Dec 2003 17:57:02 +0000 (17:57 +0000)
21 files changed:
dab/Makefile [new file with mode: 0644]
dab/algor.C [new file with mode: 0644]
dab/algor.h [new file with mode: 0644]
dab/board.C [new file with mode: 0644]
dab/board.h [new file with mode: 0644]
dab/box.C [new file with mode: 0644]
dab/box.h [new file with mode: 0644]
dab/dab.6 [new file with mode: 0644]
dab/defs.h [new file with mode: 0644]
dab/gamescreen.C [new file with mode: 0644]
dab/gamescreen.h [new file with mode: 0644]
dab/human.C [new file with mode: 0644]
dab/human.h [new file with mode: 0644]
dab/main.C [new file with mode: 0644]
dab/player.C [new file with mode: 0644]
dab/player.h [new file with mode: 0644]
dab/random.C [new file with mode: 0644]
dab/random.h [new file with mode: 0644]
dab/test.C [new file with mode: 0644]
dab/ttyscrn.C [new file with mode: 0644]
dab/ttyscrn.h [new file with mode: 0644]

diff --git a/dab/Makefile b/dab/Makefile
new file mode 100644 (file)
index 0000000..ed03c89
--- /dev/null
@@ -0,0 +1,12 @@
+#      $NetBSD: Makefile,v 1.1.1.1 2003/12/26 17:57:02 christos Exp $
+
+WARNS=2
+DPADD+=${LIBSTDCPP} ${LIBCURSES} ${LIBTERMCAP} ${LIBM}
+LDADD+=-lstdc++ -lcurses -ltermcap -lm
+
+PROG=dab
+MAN=dab.6
+SRCS=algor.C board.C main.C human.C box.C player.C gamescreen.C \
+    ttyscrn.C random.C
+
+.include <bsd.prog.mk>
diff --git a/dab/algor.C b/dab/algor.C
new file mode 100644 (file)
index 0000000..d8a8950
--- /dev/null
@@ -0,0 +1,314 @@
+/*     $NetBSD: algor.C,v 1.1.1.1 2003/12/26 17:57:03 christos Exp $   */
+
+/*-
+ * Copyright (c) 2003 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Christos Zoulas.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *        This product includes software developed by the NetBSD
+ *        Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * algor.C: Computer algorithm
+ */
+#include "defs.h"
+RCSID("$Id: algor.C,v 1.1.1.1 2003/12/26 17:57:03 christos Exp $")
+
+#include "algor.h"
+#include "board.h"
+#include "box.h"
+#include "random.h"
+
+ALGOR::ALGOR(const char c) : PLAYER(c)
+{
+#ifdef notyet
+    // Single Edges = (x + y) * 2
+    _edge1 = (_b.nx() * _b.ny()) * 2;
+    // Shared Edges = (x * (y - 1)) + ((x - 1) * y)
+    _edge2 = (_b.nx() * (_b.ny() - 1)) + ((_b.nx() - 1) * _b.ny());
+    // Maximum Edges filled before closure = x * y * 2
+    _maxedge = _b.nx() * _b.ny() * 2;
+#endif
+}
+
+// Find the first closure, i.e. a box that has 3 edges
+int ALGOR::find_closure(size_t& y, size_t& x, int& dir, BOARD& b)
+{
+    RANDOM rdy(b.ny()), rdx(b.nx());
+
+    for (y = rdy(); y < b.ny(); y = rdy()) {
+       rdx.clear();
+       for (x = rdx(); x < b.nx(); x = rdx()) {
+           BOX box(y, x, b);
+           if (box.count() == 3) {
+               for (dir = BOX::first; dir < BOX::last; dir++)
+                   if (!box.isset(dir))
+                       return 1;
+               b.abort("find_closure: 3 sided box[%d,%d] has no free sides",
+                       y, x);
+           }
+       }
+    }
+    return 0;
+}
+
+#if 0
+size_t ALGOR::find_single()
+{
+    size_t ne;
+
+    // Find the number of single edges in use
+    for (size_t x = 0; x < b.nx(); x++) {
+       BOX tbox(0, x, b);
+       ne += tbox.isset(BOX::top);
+       BOX bbox(b.ny() - 1, x, b);
+       ne += bbox.isset(BOX::bottom);
+    }
+    for (size_t y = 0; y < _b.ny(); y++) {
+       BOX lbox(y, 0, b);
+       ne += lbox.isset(BOX::left);
+       BOX rbox(y,_b.nx() - 1, b);
+       ne += rbox.isset(BOX::right);
+    }
+    return ne;
+}
+#endif
+
+
+// Count a closure, by counting all boxes that we can close in the current
+// move
+size_t ALGOR::count_closure(size_t& y, size_t& x, int& dir, BOARD& b)
+{
+    size_t i = 0;
+    size_t tx, ty;
+    int tdir, mv;
+
+    while (find_closure(ty, tx, tdir, b)) {
+       if (i == 0) {
+           // Mark the beginning of the closure
+           x = tx;
+           y = ty;
+           dir = tdir;
+       }
+       if ((mv = b.domove(ty, tx, tdir, getWho())) == -1)
+           b.abort("count_closure: Invalid move (%d, %d, %d)", y, x, dir);
+       else
+           i += mv;
+    }
+    return i;
+}
+
+
+/*
+ * Find the largest closure, by closing all possible closures.
+ * return the number of boxes closed in the maximum closure,
+ * and the first box of the maximum closure in (x, y, dir)
+ */
+int ALGOR::find_max_closure(size_t& y, size_t& x, int& dir, const BOARD& b)
+{
+    BOARD nb(b);
+    int tdir, maxdir = -1;
+    size_t nbox, maxbox = 0;
+    size_t tx, ty, maxx = ~0, maxy = ~0;
+
+    while ((nbox = count_closure(ty, tx, tdir, nb)) != 0)
+       if (nbox > maxbox) {
+           // This closure is better, update max
+           maxbox = nbox;
+           maxx = tx;
+           maxy = ty;
+           maxdir = tdir;
+       }
+
+    // Return the max found
+    y = maxy;
+    x = maxx;
+    dir = maxdir;
+    return maxbox;
+}
+
+
+// Find if a turn does not result in a capture on the given box
+// and return the direction if found.
+int ALGOR::try_good_turn(BOX& box, size_t y, size_t x, int& dir, BOARD& b)
+{
+    // Sanity check; we must have a good box
+    if (box.count() >= 2)
+       b.abort("try_good_turn: box[%d,%d] has more than 2 sides occupied",
+               y, x);
+
+    // Make sure we don't make a closure in an adjacent box.
+    // We use a random direction to randomize the game
+    RANDOM rd(BOX::last);
+    for (dir = rd(); dir < BOX::last; dir = rd())
+       if (!box.isset(dir)) {
+           size_t by = y + BOX::edges[dir].y;
+           size_t bx = x + BOX::edges[dir].x;
+           if (!b.bounds(by, bx))
+               return 1;
+
+           BOX nbox(by, bx, b);
+           if (nbox.count() < 2)
+               return 1;
+       }
+
+    return 0;
+}
+
+
+// Try to find a turn that does not result in an opponent closure, and
+// return it in (x, y, dir); if not found return 0.
+int ALGOR::find_good_turn(size_t& y, size_t& x, int& dir, const BOARD& b)
+{
+    BOARD nb(b);
+    RANDOM rdy(b.ny()), rdx(b.nx());
+
+    for (y = rdy(); y < b.ny(); y = rdy()) {
+       rdx.clear();
+       for (x = rdx(); x < b.nx(); x = rdx()) {
+           BOX box(y, x, nb);
+           if (box.count() < 2 && try_good_turn(box, y, x, dir, nb))
+               return 1;
+       }
+    }
+    return 0;
+}
+
+// On a box with 2 edges, return the first or the last free edge, depending
+// on the order specified
+int ALGOR::try_bad_turn(BOX& box, size_t& y, size_t& x, int& dir, BOARD& b,
+                       int last)
+{
+    if (4 - box.count() <= last)
+       b.abort("try_bad_turn: Called at [%d,%d] for %d with %d",
+               y, x, last, box.count());
+    for (dir = BOX::first; dir < BOX::last; dir++)
+       if (!box.isset(dir)) {
+           if (!last)
+               return 1;
+           else
+               last--;
+       }
+    return 0;
+}
+
+// Find a box that has 2 edges and return the first free edge of that
+// box or the last free edge of that box
+int ALGOR::find_bad_turn(size_t& y, size_t& x, int& dir, BOARD& b, int last)
+{
+    RANDOM rdy(b.ny()), rdx(b.nx());
+    for (y = rdy(); y < b.ny(); y = rdy()) {
+       rdx.clear();
+       for (x = rdx(); x < b.nx(); x = rdx()) {
+           BOX box(y, x, b);
+           if ((4 - box.count()) > last &&
+               try_bad_turn(box, y, x, dir, b, last))
+               return 1;
+       }
+    }
+    return 0;
+}
+
+int ALGOR::find_min_closure1(size_t& y, size_t& x, int& dir, const BOARD& b,
+                           int last)
+{
+    BOARD nb(b);
+    int tdir, mindir = -1, xdir, mv;
+    // number of boxes per closure
+    size_t nbox, minbox = nb.nx() * nb.ny() + 1;
+    size_t tx, ty, minx = ~0, miny = ~0;
+
+    while (find_bad_turn(ty, tx, tdir, nb, last)) {
+
+        // Play a bad move that would cause the opponent's closure
+       if ((mv = nb.domove(ty, tx, tdir, getWho())) != 0)
+           b.abort("find_min_closure1: Invalid move %d (%d, %d, %d)", mv,
+                   ty, tx, tdir);
+
+        // Count the opponent's closure
+       if ((nbox = count_closure(y, x, xdir, nb)) == 0)
+           b.abort("find_min_closure1: no closure found");
+
+       if (nbox <= minbox) {
+           // This closure has fewer boxes
+           minbox = nbox;
+           minx = tx;
+           miny = ty;
+           mindir = tdir;
+       }
+    }
+
+    y = miny;
+    x = minx;
+    dir = mindir;
+    return minbox;
+}
+
+
+// Search for the move that makes the opponent close the least number of
+// boxes; returns 1 if a move found, 0 otherwise
+int ALGOR::find_min_closure(size_t& y, size_t& x, int& dir, const BOARD& b)
+{
+    size_t x1, y1;
+    int dir1;
+    int count = b.ny() * b.nx() + 1, count1;
+
+    for (size_t i = 0; i < 3; i++)
+       if (count > (count1 = find_min_closure1(y1, x1, dir1, b, i))) {
+           count = count1;
+           y = y1;
+           x = x1;
+           dir = dir1;
+       }
+
+    return (size_t) count != b.ny() * b.nx() + 1;
+}
+
+// Return a move in (y, x, dir)
+void ALGOR::play(const BOARD& b, size_t& y, size_t& x, int& dir)
+{
+    // See if we can close the largest closure available
+    if (find_max_closure(y, x, dir, b))
+       return;
+
+#ifdef notyet
+    size_t sgl = find_single();
+    size_t dbl = find_double();
+#endif
+
+    // See if we can play an edge without giving the opponent a box
+    if (find_good_turn(y, x, dir, b))
+       return;
+
+    // Too bad, find the move that gives the opponent the fewer boxes
+    if (find_min_closure(y, x, dir, b))
+       return;
+}
diff --git a/dab/algor.h b/dab/algor.h
new file mode 100644 (file)
index 0000000..862c93a
--- /dev/null
@@ -0,0 +1,86 @@
+/*     $NetBSD: algor.h,v 1.1.1.1 2003/12/26 17:57:03 christos Exp $   */
+
+/*-
+ * Copyright (c) 2003 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Christos Zoulas.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *        This product includes software developed by the NetBSD
+ *        Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * algor.h: Computer's algorithm
+ */
+
+#ifndef _H_ALGOR
+#define _H_ALGOR
+
+#include "player.h"
+
+class BOARD;
+class BOX;
+
+class ALGOR : public PLAYER {
+  public:
+    ALGOR(const char c);
+    // Return a proposed move in (y, x, dir)
+    void play(const BOARD& b, size_t& y, size_t& x, int& dir);
+
+  private:
+    // Closure searches
+    int find_closure(size_t& y, size_t& x, int& dir, BOARD& b);
+    int find_max_closure(size_t& y, size_t& x, int& dir, const BOARD& b);
+    int find_min_closure1(size_t& y, size_t& x, int& dir, const BOARD& b,
+                         int last);
+    int find_min_closure(size_t& y, size_t& x, int& dir, const BOARD& b);
+
+    // Move searches
+    int find_good_turn(size_t& y, size_t& x, int& dir, const BOARD& b);
+    int find_bad_turn(size_t& y, size_t& x, int& dir, BOARD& b, int last);
+
+    // Move Attempts
+    int try_bad_turn(BOX& box, size_t& y, size_t& x, int& dir, BOARD& b,
+                    int last);
+    int try_good_turn(BOX& box, size_t y, size_t x, int& dir, BOARD& b);
+
+    // Utils
+    size_t count_closure(size_t& y, size_t& x, int& dir, BOARD& b);
+
+#ifdef notyet
+    size_t find_single(void);
+#endif
+
+    size_t _edge1;
+    size_t _edge2;
+    size_t _maxedge;
+};
+
+#endif
diff --git a/dab/board.C b/dab/board.C
new file mode 100644 (file)
index 0000000..38827b2
--- /dev/null
@@ -0,0 +1,260 @@
+/*     $NetBSD: board.C,v 1.1.1.1 2003/12/26 17:57:03 christos Exp $   */
+
+/*-
+ * Copyright (c) 2003 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Christos Zoulas.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *        This product includes software developed by the NetBSD
+ *        Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * board.C: Board manipulations
+ */
+#include "defs.h"
+RCSID("$Id: board.C,v 1.1.1.1 2003/12/26 17:57:03 christos Exp $")
+
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+#include "board.h"
+#include "gamescreen.h"
+#include "box.h"
+#include "player.h"
+
+BOARD::BOARD(size_t y, size_t x, GAMESCREEN* scrn) :
+    _ny(y),
+    _nx(x),
+    _scrn(scrn)
+{
+    _ty = 2 * _ny + 1;
+    _tx = 2 * _nx + 1;
+
+    _b = new int*[_ty];
+
+    for (y = 0; y < _ty; y++)
+       _b[y] = new int[_tx];
+
+    init();
+}
+
+BOARD::BOARD(const BOARD& b) :
+    _ty(b._ty),
+    _tx(b._tx),
+    _ny(b._ny),
+    _nx(b._nx),
+    _scrn(NULL)
+{
+    _b = new int*[_ty];
+
+    for (size_t y = 0; y < _ty; y++) {
+       _b[y] = new int[_tx];
+       (void) memcpy(_b[y], b._b[y], _tx * sizeof(int));
+    }
+}
+
+BOARD::~BOARD()
+{
+    size_t y;
+
+    for (y = 0; y < _ty; y++)
+       delete[] _b[y];
+
+    delete[] _b;
+}
+
+// Clear all boxes and reset state for a new game
+void BOARD::init(void)
+{
+    size_t x, y;
+
+    for (y = 0; y < _ny; y++) 
+       for (x = 0; x < _nx; x++) {
+           BOX box(y, x, *this);
+           box.reset();
+       }
+}
+
+/*
+ * Make a move for player with initial 'c', adding an edge at box(x, y)
+ * and the specified direction.
+ * returns:
+ *     -1:     Invalid move
+ *      n:     Number of closures n E [0..2]
+ */
+int BOARD::domove(size_t y, size_t x, int dir, char c)
+{
+    int closed = 0;
+
+    // Check if out of bounds
+    if (!bounds(y, x))
+       return -1;
+
+    BOX box1(y, x, *this);
+
+    // Check if the edge is already there
+    if (box1.isset(dir))
+       return -1;
+
+    box1.set(dir);
+
+    if (box1.count() == 4) {
+       // New box; name it and count it
+       box1.name() = c;
+       closed++;
+    }
+
+    box1.paint();
+
+    // Check other box
+    x += BOX::edges[dir].x;
+    y += BOX::edges[dir].y;
+
+    if (bounds(y, x)) {
+       BOX box2(y, x, *this);
+       if (box2.count() == 4) {
+           box2.name() = c;
+           box2.paint();
+           closed++;
+       }
+    }
+    return closed;
+}
+
+// Return true if the board is full
+int BOARD::full(void) const
+{
+    for (size_t y = 0; y < _ny; y++)
+       for (size_t x = 0; x < _nx; x++) {
+           BOX box(y, x, (BOARD&) *this);
+           if (box.count() != 4)
+               return 0;
+       }
+    return 1;
+}
+
+// Return if the coordinates are within bounds; we don't check for < 0,
+// since size_t is unsigned
+int BOARD::bounds(size_t y, size_t x) const
+{
+    return x < _nx && y < _ny;
+}
+
+// Paint all boxes, effectively redrawing the board
+void BOARD::paint(void) const
+{
+    for (size_t y = 0; y < _ny; y++)
+       for (size_t x = 0; x < _nx; x++) {
+           BOX box(y, x, (BOARD&) *this);
+           box.paint();
+       }
+}
+
+// Clear the screen
+void BOARD::clean(void) const
+{
+    if (!_scrn)
+       return;
+    _scrn->clean();
+}
+
+// Move cursor to x, y
+void BOARD::setpos(size_t y, size_t x) const
+{
+    if (!_scrn)
+       return;
+    _scrn->moveto(y, x);
+    _scrn->redraw();
+}
+
+// Return character indicating move
+int BOARD::getmove(void) const
+{
+    if (!_scrn)
+       return 'q';
+    _scrn->redraw();
+    return _scrn->getinput();
+}
+
+// Ring the bell
+void BOARD::bell(void) const
+{
+    if (!_scrn)
+       return;
+    _scrn->bell();
+}
+
+// Post the score in the current game for player i
+void BOARD::score(size_t i, const PLAYER& p)
+{
+    if (_scrn == NULL)
+       return;
+    _scrn->score(i, p);
+}
+
+// Post the number of games won for player i
+void BOARD::games(size_t i, const PLAYER& p)
+{
+    if (_scrn == NULL)
+       return;
+    _scrn->games(i, p);
+}
+
+// Post the total score for player i
+void BOARD::total(size_t i, const PLAYER& p)
+{
+    if (_scrn == NULL)
+       return;
+    _scrn->total(i, p);
+}
+
+// Post the total score for player i
+void BOARD::ties(const PLAYER& p)
+{
+    if (_scrn == NULL)
+       return;
+    _scrn->ties(p);
+}
+
+// Internal algorithm error; post and abort
+void BOARD::abort(const char* s, ...) const
+{
+    for (size_t i = 0; i < _ny; i++)
+       fprintf(stderr, "\n");
+
+    va_list ap;
+    fprintf(stderr, "Algorithm internal error: ");
+    va_start(ap, s);
+    vfprintf(stderr, s, ap);
+    va_end(ap);
+    fprintf(stderr, "\n");
+    ::abort();
+}
diff --git a/dab/board.h b/dab/board.h
new file mode 100644 (file)
index 0000000..9a21a0a
--- /dev/null
@@ -0,0 +1,92 @@
+/*     $NetBSD: board.h,v 1.1.1.1 2003/12/26 17:57:03 christos Exp $   */
+
+/*-
+ * Copyright (c) 2003 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Christos Zoulas.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *        This product includes software developed by the NetBSD
+ *        Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * board.h: Board functions
+ */
+
+#ifndef _H_BOARD
+#define _H_BOARD
+
+#include <stdlib.h>
+
+class GAMESCREEN;
+class PLAYER;
+
+class BOARD {
+  public:
+    // Constructors and destructor
+    BOARD(size_t y, size_t x, GAMESCREEN* scrn);// For the main screen
+    BOARD(const BOARD& b);                     // For scratch screens
+    ~BOARD();
+
+    // member access
+    size_t nx(void) const { return _nx; }
+    size_t ny(void) const { return _ny; }
+    size_t tx(void) const { return _tx; }
+    size_t ty(void) const { return _ty; }
+    GAMESCREEN* getScrn(void) const { return _scrn; }
+    int& data(size_t y, size_t x) { return _b[y][x]; }
+
+    // Computing
+    int domove(size_t y, size_t x, int dir, char c);   // Play move
+    void init(void);                                   // Initialize a new game
+    int full(void) const;                              // True if no more moves
+    int bounds(size_t y, size_t x) const;              // True if in bounds
+
+    // Screen updates
+    void paint(void) const;                            // Redraw screen
+    void clean(void) const;                            // Clear screen
+    void setpos(size_t y, size_t x) const;             // move cursor to pos
+    int getmove(void) const;                           // Return move
+    void bell(void) const;                             // Beep!
+    void score(size_t i, const PLAYER& p);             // Post score
+    void games(size_t i, const PLAYER& p);             // Post games
+    void total(size_t i, const PLAYER& p);             // Post totals
+    void ties(const PLAYER& p);                                // Post ties
+    void abort(const char *s, ...) const;              // Algorithm error
+
+
+  private:
+    size_t     _ty, _tx;       // number of symbols in x and y dimension
+    size_t     _ny, _nx;       // number of boxes in the x and y dimension
+    int**      _b;             // board array of symbols
+    GAMESCREEN*        _scrn;          // screen access, if we have one
+};
+
+#endif
diff --git a/dab/box.C b/dab/box.C
new file mode 100644 (file)
index 0000000..99e041d
--- /dev/null
+++ b/dab/box.C
@@ -0,0 +1,157 @@
+/*     $NetBSD: box.C,v 1.1.1.1 2003/12/26 17:57:03 christos Exp $     */
+
+/*-
+ * Copyright (c) 2003 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Christos Zoulas.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *        This product includes software developed by the NetBSD
+ *        Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * box.C: Box computations
+ */
+#include "defs.h"
+RCSID("$Id: box.C,v 1.1.1.1 2003/12/26 17:57:03 christos Exp $")
+
+#include "box.h"
+#include "board.h"
+#include "gamescreen.h"
+#include <curses.h>
+
+const POINT BOX::edges[BOX::last] =
+    { { 0, -1 }, { 0, 1 }, { -1, 0 }, { 1, 0 } };
+const POINT BOX::corners[BOX::last] =
+    { { -1, -1 }, { -1, 1 }, { 1, -1 }, { 1, 1 } };
+const int  BOX::syms[BOX::last] =
+    { GAMESCREEN::GS_HLINE, GAMESCREEN::GS_HLINE,
+      GAMESCREEN::GS_VLINE, GAMESCREEN::GS_VLINE };
+
+BOX::BOX(size_t py, size_t px, BOARD& b) :
+    _b(b)
+{
+    _centery = py * 2 + 1;
+    _centerx = px * 2 + 1;
+}
+
+void BOX::addcorner(size_t y, size_t x)
+{
+    char sym;
+    _b.getScrn()->moveto(y, x);
+    if (x == 0) {
+       if (y == 0)
+           sym = GAMESCREEN::GS_ULCORNER;
+       else if (y == _b.ty() - 1)
+           sym = GAMESCREEN::GS_LLCORNER;
+       else
+           sym = GAMESCREEN::GS_LTEE;
+    } else if (x == _b.tx() - 1) {
+       if (y == 0)
+           sym = GAMESCREEN::GS_URCORNER;
+       else if (y == _b.ty() - 1)
+           sym = GAMESCREEN::GS_LRCORNER;
+       else
+           sym = GAMESCREEN::GS_RTEE;
+    } else if (y == 0)
+       sym = GAMESCREEN::GS_TTEE;
+    else if (y == _b.ty() - 1)
+       sym = GAMESCREEN::GS_BTEE;
+    else
+       sym = GAMESCREEN::GS_PLUS;
+
+    _b.getScrn()->addedge(sym);
+}
+
+// Paint a box
+void BOX::paint(void)
+{
+    int e;
+    if (_b.getScrn() == NULL)
+       return;
+
+    _b.getScrn()->moveto(_centery, _centerx);
+    _b.getScrn()->addsym(name());
+
+    for (e = BOX::first; e < BOX::last; e++) {
+       addcorner(_centery + corners[e].y, _centerx + corners[e].x);
+       _b.getScrn()->moveto(_centery + edges[e].y, _centerx + edges[e].x);
+       _b.getScrn()->addedge(edge((EDGE) e));
+    }
+    _b.getScrn()->redraw();
+}
+
+// Return the name
+int& BOX::name(void)
+{
+    return _b.data(_centery, _centerx);
+}
+
+// Set an edge
+void BOX::set(int e)
+{
+    _b.data(_centery + edges[e].y, _centerx + edges[e].x) = syms[e];
+}
+
+// Clear an edge
+void BOX::clr(int e)
+{
+    _b.data(_centery + edges[e].y, _centerx + edges[e].x) = ' ';
+}
+
+// Test an edge
+int BOX::isset(int e) const
+{
+    return _b.data(_centery + edges[e].y, _centerx + edges[e].x) != ' ';
+}
+
+// Return the edge
+int& BOX::edge(int e)
+{
+    return _b.data(_centery + edges[e].y, _centerx + edges[e].x);
+}
+
+// Count the number of edges set in the box
+int BOX::count(void) const
+{
+    int cnt = 0;
+
+    for (int e = BOX::first; e < BOX::last; e++)
+       cnt += isset((EDGE) e);
+    return cnt;
+}
+
+// Clear the box
+void BOX::reset(void)
+{
+    for (int e = BOX::first; e < BOX::last; e++)
+       clr((EDGE) e);
+    name() = ' ';
+} 
diff --git a/dab/box.h b/dab/box.h
new file mode 100644 (file)
index 0000000..015e9a7
--- /dev/null
+++ b/dab/box.h
@@ -0,0 +1,100 @@
+/*     $NetBSD: box.h,v 1.1.1.1 2003/12/26 17:57:03 christos Exp $     */
+
+/*-
+ * Copyright (c) 2003 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Christos Zoulas.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *        This product includes software developed by the NetBSD
+ *        Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * box.C: Single box utilities; A box is an entity with four edges, four
+ *       corners, and a center that maps directly to a board
+ */
+
+#ifndef _H_BOX
+#define _H_BOX
+
+#include <stdlib.h>
+
+class BOARD;
+
+class POINT {
+  public:
+    int x;
+    int y;
+};
+
+class BOX {
+  public:
+    enum EDGE {
+       first  = 0,
+       top    = 0,
+       bottom = 1,
+       left   = 2,
+       right  = 3,
+       last   = 4,
+    };
+
+    BOX(size_t py, size_t px, BOARD& b);
+
+    void reset(void);          // Clear a box
+    void paint(void);          // Paint a box
+
+    // Member access
+    int& name(void);
+    int& edge(int e);
+
+    // Edge maniputations
+    void set(int e);
+    void clr(int e);
+    int isset(int e) const;
+
+    int count(void) const;     // Count the number of edges in use
+
+    // Useful constants
+    // Relative coordinates of the edges from the center of the box.
+    static const POINT edges[BOX::last];
+    // Relative coordinates of the corners from the center of the box.
+    static const POINT corners[BOX::last];
+    // Character symbols of the four edges
+    static const int syms[BOX::last];
+
+  private:
+    void addcorner(size_t y, size_t x);        // add a corner character
+
+    size_t _centerx;   // Coordinates of the center in board units
+    size_t _centery;
+    BOARD& _b;         // The board we refer to
+};
+
+#endif
diff --git a/dab/dab.6 b/dab/dab.6
new file mode 100644 (file)
index 0000000..a5feab5
--- /dev/null
+++ b/dab/dab.6
@@ -0,0 +1,110 @@
+.\"    $NetBSD: dab.6,v 1.1.1.1 2003/12/26 17:57:04 christos Exp $
+.\"
+.\" Copyright (c) 2003 Thomas Klausner.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\" 3. The name of the author may not be used to endorse or promote products
+.\"    derived from this software without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+.\"
+.Dd December 24, 2003
+.Dt DAB 6
+.Os
+.Sh NAME
+.Nm dab
+.Nd Dots and Boxes game
+.Sh SYNOPSIS
+.Nm
+.Op Fl aw
+.Op Fl n Ar ngames
+.Op Fl p Ao Ar c|h Ac Ns Ao Ar c|h Ac
+.Op Ar xdim Oo Ar ydim Oc
+.Sh DESCRIPTION
+.Nm
+is a game where each player tries to complete the most
+boxes.
+A turn consists of putting one border of a box; the player
+setting the fourth and final border of a box gets the
+point for the box and has another turn.
+.Pp
+The keys used are the vi keys:
+.Ic k
+for up,
+.Ic j
+for down,
+.Ic h
+for left, and
+.Ic l
+for right.
+To switch between even and odd rows, use one of the following
+keys:
+.Ic u
+.Pq diagonal right up ,
+.Ic y
+.Pq diagonal left up ,
+.Ic b
+.Pq diagonal left down ,
+.Ic n
+.Pq diagonal right down ;
+.Aq Ic space
+sets a new border,
+.Ic CTRL-L
+and
+.Ic CTRL-R
+redraw the screen, and
+.Ic q
+quits the game.
+.Pp
+Support options are:
+.Bl -tag -width XXnXngamesXXXXX
+.It Fl a
+Don't use the alternate character set.
+.It Fl n Ar ngames
+.Ar ngames
+games will be played.
+.Pq Especially useful in Fl p Ar cc No mode.
+.It Fl p Ao Ar c|h Ac Ns Ao Ar c|h Ac
+Select which of the two players is a human
+or a computer.
+The first argument is the first player;
+.Ic c
+stands for computer and
+.Ic h
+for human.
+.It Fl w 
+Wait for a character press between games.
+.El
+.Pp
+.Ar xdim
+and
+.Ar ydim
+define the size of the board in the x and y
+dimensions.
+.Sh AUTHORS
+.An Christos Zoulas
+.Aq christos@NetBSD.org
+.Sh SEE ALSO
+.Rs
+.%A Elwyn R. Berlekamp
+.%T The Dots and Boxes Game: Sophisticated Child's Play
+.%D 2000
+.%I A K Peters
+.%O http://www.akpeters.com/book.asp?bID=111
+.Re
diff --git a/dab/defs.h b/dab/defs.h
new file mode 100644 (file)
index 0000000..b0bda57
--- /dev/null
@@ -0,0 +1,51 @@
+/*     $NetBSD: defs.h,v 1.1.1.1 2003/12/26 17:57:03 christos Exp $    */
+
+/*-
+ * Copyright (c) 2003 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Christos Zoulas.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *        This product includes software developed by the NetBSD
+ *        Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * defs.h: Macro defines
+ */
+
+#ifndef _H_DEFS
+#define _H_DEFS
+
+#include <stdlib.h>
+
+#define RCSID(id) \
+    static const char *rcsid(const char* x) { return x ? rcsid(id) : x; }
+
+#endif
diff --git a/dab/gamescreen.C b/dab/gamescreen.C
new file mode 100644 (file)
index 0000000..11c65df
--- /dev/null
@@ -0,0 +1,50 @@
+/*     $NetBSD: gamescreen.C,v 1.1.1.1 2003/12/26 17:57:03 christos Exp $      */
+
+/*-
+ * Copyright (c) 2003 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Christos Zoulas.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *        This product includes software developed by the NetBSD
+ *        Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * gamescreen.C: Common screen functions
+ */
+#include "defs.h"
+RCSID("$Id: gamescreen.C,v 1.1.1.1 2003/12/26 17:57:03 christos Exp $")
+
+#include "gamescreen.h"
+
+// Nothing to do
+GAMESCREEN::~GAMESCREEN()
+{
+}
diff --git a/dab/gamescreen.h b/dab/gamescreen.h
new file mode 100644 (file)
index 0000000..ca90cb3
--- /dev/null
@@ -0,0 +1,79 @@
+/*     $NetBSD: gamescreen.h,v 1.1.1.1 2003/12/26 17:57:03 christos Exp $      */
+
+/*-
+ * Copyright (c) 2003 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Christos Zoulas.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *        This product includes software developed by the NetBSD
+ *        Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * screen.h: Screen base class
+ */
+
+#ifndef _H_GAMESCREEN
+#define _H_GAMESCREEN
+
+#include <stdlib.h>
+
+class PLAYER;
+
+class GAMESCREEN {
+  public:
+    enum EDGE {
+       GS_HLINE,
+       GS_VLINE,
+       GS_ULCORNER,
+       GS_URCORNER,
+       GS_LLCORNER,
+       GS_LRCORNER,
+       GS_LTEE,
+       GS_RTEE,
+       GS_TTEE,
+       GS_BTEE,
+       GS_PLUS
+    };
+    virtual ~GAMESCREEN();
+    virtual void clean(void) = 0;                      // Clear screen
+    virtual void moveto(size_t y, size_t x) = 0;       // Move to x, y
+    virtual void addsym(const int sym) = 0;            // Add character symbol
+    virtual void addedge(const int sym) = 0;           // Add character symbol
+    virtual void redraw(void) = 0;                     // Refresh
+    virtual int getinput(void) = 0;                    // Get user input
+    virtual void bell(void) = 0;                       // Beep
+    virtual void score(size_t p, const PLAYER& p) = 0; // Post current score
+    virtual void games(size_t p, const PLAYER& p) = 0; // Post games won
+    virtual void total(size_t p, const PLAYER& p) = 0; // Post total score
+    virtual void ties(const PLAYER& p) = 0;            // Post tie games
+};
+
+#endif
diff --git a/dab/human.C b/dab/human.C
new file mode 100644 (file)
index 0000000..c9cd799
--- /dev/null
@@ -0,0 +1,151 @@
+/*     $NetBSD: human.C,v 1.1.1.1 2003/12/26 17:57:03 christos Exp $   */
+
+/*-
+ * Copyright (c) 2003 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Christos Zoulas.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *        This product includes software developed by the NetBSD
+ *        Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * human.C: Human interface for dots, using rogue-like keys.
+ */
+#include "defs.h"
+RCSID("$Id: human.C,v 1.1.1.1 2003/12/26 17:57:03 christos Exp $")
+
+#include "human.h"
+#include "board.h"
+#include "box.h"
+
+#define CONTROL(a) ((a) & 037)
+
+HUMAN::HUMAN(const char c) :
+    PLAYER(c),
+    _curx(0),
+    _cury(1)
+{
+}
+
+void HUMAN::play(const BOARD& b, size_t& y, size_t& x, int& dir)
+{
+    int mv;
+    b.setpos(_cury, _curx);
+
+    for (;;) {
+       switch (mv = b.getmove()) {
+       case 'h': case 'H':
+           _curx -= 2;
+           break;
+
+       case 'l': case 'L':
+           _curx += 2;
+           break;
+
+       case 'k': case 'K':
+           _cury -= 2;
+           break;
+
+       case 'j': case 'J':
+           _cury += 2;
+           break;
+
+       case 'u': case 'U':
+           _curx += 1;
+           _cury -= 1;
+           break;
+
+       case 'y': case 'Y':
+           _curx -= 1;
+           _cury -= 1;
+           break;
+
+       case 'b': case 'B':
+           _curx -= 1;
+           _cury += 1;
+           break;
+
+       case 'n': case 'N':
+           _curx += 1;
+           _cury += 1;
+           break;
+
+       case 'q': case 'Q':
+           exit(0);
+
+       case CONTROL('L'): case CONTROL('R'):
+           b.clean();
+           b.paint();
+           break;
+
+       case ' ':
+           {
+               x = _curx / 2;
+               y = _cury / 2;
+
+               if (_cury & 1) {
+                   if (_curx == 0)
+                       dir = BOX::left;
+                   else {
+                       x--;
+                       dir = BOX::right;
+                   }
+               }
+
+               if (_curx & 1) {
+                   if (_cury == 0)
+                       dir = BOX::top;
+                   else {
+                       y--;
+                       dir = BOX::bottom;
+                   }
+               }
+           }
+           return;
+
+       default:
+           break;
+       }
+
+        // We add 2 before the comparison to avoid underflow
+       if ((2 + _curx) - (_curx & 1) < 2)
+           _curx = (b.nx() * 2) + (_curx & 1);
+       if (_curx >= (b.nx() * 2) + 1)
+           _curx = (_curx & 1);
+
+       if ((2 + _cury) - (_cury & 1) < 2)
+           _cury = (b.ny() * 2) + (_cury & 1);
+       if (_cury >= (b.ny() * 2) + 1)
+           _cury = (_cury & 1);
+
+       b.setpos(_cury, _curx);
+    }
+}
diff --git a/dab/human.h b/dab/human.h
new file mode 100644 (file)
index 0000000..b245ee1
--- /dev/null
@@ -0,0 +1,59 @@
+/*     $NetBSD: human.h,v 1.1.1.1 2003/12/26 17:57:03 christos Exp $   */
+
+/*-
+ * Copyright (c) 2003 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Christos Zoulas.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *        This product includes software developed by the NetBSD
+ *        Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * human.h: Human input interface
+ */
+
+#ifndef _H_HUMAN
+#define _H_HUMAN
+#include <stdlib.h>
+#include "player.h"
+
+class BOARD;
+
+class HUMAN : public PLAYER {
+  public:
+    HUMAN(const char c);
+    // Return move in y, x, and dir
+    void play(const BOARD& b, size_t& y, size_t& x, int& dir);
+  private:
+    size_t _curx, _cury;       // Current cursor position
+};
+
+#endif
diff --git a/dab/main.C b/dab/main.C
new file mode 100644 (file)
index 0000000..5f7a644
--- /dev/null
@@ -0,0 +1,196 @@
+/*     $NetBSD: main.C,v 1.1.1.1 2003/12/26 17:57:03 christos Exp $    */
+
+/*-
+ * Copyright (c) 2003 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Christos Zoulas.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *        This product includes software developed by the NetBSD
+ *        Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * main.C: Main dots program
+ */
+#include "defs.h"
+RCSID("$Id: main.C,v 1.1.1.1 2003/12/26 17:57:03 christos Exp $")
+
+#include <iostream>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <err.h>
+#include "algor.h"
+#include "board.h"
+#include "human.h"
+#include "ttyscrn.h"
+
+// Print the command line usage
+static void usage(char* pname)
+{
+    char* p = strrchr(pname, '/');
+    if (p)
+       p++;
+    else
+       p = pname;
+    std::cerr << "Usage: " << p
+       << " [-w] [-p <c|h><c|h>] [-n <ngames>] [<ydim> [<xdim>]]" << std::endl;
+}
+
+// Play a single game
+static void play(BOARD& b, PLAYER* p[2])
+{
+    // Initialize
+    b.init();
+    p[0]->init();
+    p[1]->init();
+    b.paint();
+
+    // Alternate turns between players, scoring each turn
+    for (size_t i = 0;; i = (i + 1) & 1) {
+       b.score(i, *p[i]);
+       if (!p[i]->domove(b)) {
+           // No more moves, game over
+           break;
+       }
+       b.score(i, *p[i]);
+    }
+
+    // Find who won
+    p[0]->wl(p[1]->getScore());
+    p[1]->wl(p[0]->getScore());
+
+    // Post scores
+    b.score(0, *p[0]);
+    b.score(1, *p[1]);
+
+    // Post totals
+    b.total(0, *p[0]);
+    b.total(1, *p[1]);
+
+    // Post games
+    b.games(0, *p[0]);
+    b.games(1, *p[1]);
+
+    // Post ties
+    b.ties(*p[0]);
+}
+
+int main(int argc, char** argv)
+{
+    size_t ny, nx, nn = 1, wt = 0;
+    char* nc = "ch";
+    int c;
+    int acs = 1;
+
+    while ((c = getopt(argc, argv, "awp:n:")) != -1)
+       switch (c) {
+       case 'a':
+           acs = 0;
+           break;
+       case 'w':
+           wt++;
+           break;
+
+       case 'p':
+           nc = optarg;
+           break;
+
+       case 'n':
+           nn = atoi(optarg);
+           break;
+
+       default:
+           usage(argv[0]);
+           return 1;
+       }
+
+    // Get the size of the board if specified
+    switch (argc - optind) {
+    case 0:
+       ny = nx = 3;
+       break;
+
+    case 1:
+       ny = nx = atoi(argv[optind]);
+       break;
+
+    case 2:
+       nx = atoi(argv[optind]);
+       ny = atoi(argv[optind+1]);
+       break;
+
+    default:
+       usage(argv[0]);
+       return 1;
+    }
+    
+
+    PLAYER* p[2];
+
+    // Allocate players
+    for (size_t i = 0; i < 2; i++) {
+       char n = nc[1] == nc[0] ? i + '0' : nc[i];
+       switch (nc[i]) {
+       case 'c':
+           p[i] = new ALGOR(n);
+           break;
+
+       case 'h':
+           p[i] = new HUMAN(n);
+           break;
+
+       default:
+           usage(argv[0]);
+           return 1;
+       }
+    }
+
+    GAMESCREEN *sc = TTYSCRN::create(acs, ny, nx);
+    if (sc == NULL)
+       ::errx(1, "Dimensions too large for current screen.");
+
+    BOARD b(ny, nx, sc);
+
+    // Play games
+    while (nn--) {
+       play(b, p);
+       if (wt)
+           b.getmove();
+    }
+
+    if (wt == 0)
+       b.getmove();
+    // Cleanup
+    delete sc;
+    delete p[0];
+    delete p[1];
+    return 0;
+}
diff --git a/dab/player.C b/dab/player.C
new file mode 100644 (file)
index 0000000..2843cfa
--- /dev/null
@@ -0,0 +1,98 @@
+/*     $NetBSD: player.C,v 1.1.1.1 2003/12/26 17:57:03 christos Exp $   */
+
+/*-
+ * Copyright (c) 2003 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Christos Zoulas.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *        This product includes software developed by the NetBSD
+ *        Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * player.C: Player base class
+ */
+
+#include "defs.h"
+RCSID("$Id: player.C,v 1.1.1.1 2003/12/26 17:57:03 christos Exp $")
+
+#include "board.h"
+#include "player.h"
+
+PLAYER::PLAYER(char who) :
+    _who(who),
+    _score(0),
+    _total(0),
+    _games(0),
+    _ties(0)
+{
+}
+
+void PLAYER::init(void)
+{
+    _score = 0;
+}
+
+void PLAYER::wl(size_t sc)
+{
+    _total += _score;
+    _games += sc < _score;
+    _ties += sc == _score;
+}
+
+int PLAYER::domove(BOARD& b)
+{
+    size_t y, x;
+    int dir;
+    int score;
+
+    for (;;) {
+       if (b.full())
+           return 0;
+
+       play(b, y, x, dir);
+
+       switch (score = b.domove(y, x, dir, _who)) {
+       case 0:
+           // No closure
+           return 1;
+
+       case -1:
+           // Not a valid move
+           b.bell();
+           break;
+
+       default:
+           // Closure, play again
+           _score += score;
+           break;
+       }
+    }
+}
diff --git a/dab/player.h b/dab/player.h
new file mode 100644 (file)
index 0000000..514b9b7
--- /dev/null
@@ -0,0 +1,76 @@
+/*     $NetBSD: player.h,v 1.1.1.1 2003/12/26 17:57:03 christos Exp $  */
+
+/*-
+ * Copyright (c) 2003 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Christos Zoulas.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *        This product includes software developed by the NetBSD
+ *        Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * player.h: Player base class
+ */
+#ifndef _H_PLAYER
+#define _H_PLAYER
+
+class BOARD;
+
+#include <stdlib.h>
+
+class PLAYER {
+  public:
+    PLAYER(char who);
+    virtual void play(const BOARD& b, size_t& y, size_t& x, int& dir) = 0;
+
+    // Helper functions
+    void init(void);
+    int domove(BOARD& b);
+
+    // Member access
+    char getWho(void) const { return _who; }
+
+    // Display
+    size_t getScore(void) const { return _score; }
+    size_t getTotal(void) const { return _total; }
+    size_t getGames(void) const { return _games; }
+    size_t getTies(void) const { return _ties;   }
+    void wl(size_t sc);
+
+  private:
+    char _who;
+    size_t _score;
+    size_t _total;
+    size_t _games;
+    size_t _ties;
+};
+
+#endif
diff --git a/dab/random.C b/dab/random.C
new file mode 100644 (file)
index 0000000..a7ffbd6
--- /dev/null
@@ -0,0 +1,86 @@
+/*     $Header: /cvsroot/src/games/dab/Attic/random.C,v 1.1.1.1 2003/12/26 17:57:03 christos Exp $     */
+
+/*-
+ * Copyright (c) 2003 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Christos Zoulas.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *        This product includes software developed by the NetBSD
+ *        Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * random.C: Randomizer for the dots program
+ */
+
+#include "defs.h"
+RCSID("$Id: random.C,v 1.1.1.1 2003/12/26 17:57:03 christos Exp $")
+
+#include <time.h>
+#include <string.h>
+#include "random.h"
+
+RANDOM::RANDOM(size_t ns) :
+    _bs(ns)
+{
+    _bm = new char[(_bs >> 3) + 1];
+    clear();
+}
+
+RANDOM::~RANDOM()
+{
+    delete[] _bm;
+}
+
+// Reinitialize
+void RANDOM::clear(void)
+{
+    _nv = 0;
+    ::srand48(::time(NULL));
+    (void) ::memset(_bm, 0, (_bs >> 3) + 1);
+}
+
+// Return the next random value
+size_t RANDOM::operator() (void)
+{
+    // No more values
+    if (_nv == _bs)
+       return _bs;
+
+    for (;;) {
+       size_t r = ::lrand48();
+       size_t z = r % _bs;
+        if (!isset(z)) {
+           set(z);
+           _nv++;
+           return z;
+       }
+    }
+}
diff --git a/dab/random.h b/dab/random.h
new file mode 100644 (file)
index 0000000..e2855e9
--- /dev/null
@@ -0,0 +1,73 @@
+/*     $Header: /cvsroot/src/games/dab/random.h,v 1.1.1.1 2003/12/26 17:57:04 christos Exp $   */
+
+/*-
+ * Copyright (c) 2003 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Christos Zoulas.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *        This product includes software developed by the NetBSD
+ *        Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * random.h: Randomizer; returns a random sequence of values from [0..fx) 
+ *          returning each value exactly once. After fx calls it returns fx.
+ */
+
+#ifndef _H_RANDOM
+#define _H_RANDOM
+
+#include <stdlib.h>
+
+class RANDOM {
+  public:
+    // Constructor and destructor
+    RANDOM(size_t fx);
+    ~RANDOM();
+
+    size_t operator () (void); // Next random
+    void clear(void);          // Reset
+
+  private:
+
+    int isset(size_t z) {
+       return (_bm[z >> 3] & (1 << (z & 7))) != 0;
+    }
+
+    void set(size_t z) {
+       _bm[z >> 3] |= (1 << (z & 7));
+    }
+
+    char*      _bm;    // Bitmap indicating the numbers used
+    size_t     _nv;    // Number of values returned so far
+    size_t     _bs;    // Maximum value
+};
+
+#endif
diff --git a/dab/test.C b/dab/test.C
new file mode 100644 (file)
index 0000000..f34b011
--- /dev/null
@@ -0,0 +1,57 @@
+/*     $NetBSD: test.C,v 1.1.1.1 2003/12/26 17:57:04 christos Exp $    */
+
+/*-
+ * Copyright (c) 2003 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Christos Zoulas.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *        This product includes software developed by the NetBSD
+ *        Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * test.C: Test program for randomizer
+ */
+
+#include "defs.h"
+RCSID("$Id: test.C,v 1.1.1.1 2003/12/26 17:57:04 christos Exp $")
+
+#include <iostream>
+#include "random.h"
+
+int
+main(void)
+{
+    RANDOM rd(10);
+
+    for (size_t x = rd(); x < 10; x = rd())
+       std::cout << "x=" << x << std::endl;
+    return 0;
+}
diff --git a/dab/ttyscrn.C b/dab/ttyscrn.C
new file mode 100644 (file)
index 0000000..ee63637
--- /dev/null
@@ -0,0 +1,235 @@
+/*     $NetBSD: ttyscrn.C,v 1.1.1.1 2003/12/26 17:57:04 christos Exp $ */
+
+/*-
+ * Copyright (c) 2003 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Christos Zoulas.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *        This product includes software developed by the NetBSD
+ *        Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * ttyscrn.C: Curses screen implementation for dots
+ */
+
+#include "defs.h"
+RCSID("$Id: ttyscrn.C,v 1.1.1.1 2003/12/26 17:57:04 christos Exp $")
+
+#include <stdio.h>
+#include <curses.h>
+#include <sys/ioctl.h>
+
+#include "player.h"
+#include "ttyscrn.h"
+
+void TTYSCRN::clean(void)
+{
+    clear();
+}
+
+void TTYSCRN::moveto(size_t y, size_t x)
+{
+    move(y + TTYSCRN::offsy, x + TTYSCRN::offsx);
+}
+
+void TTYSCRN::addsym(const int sym)
+{
+    addch(sym);
+}
+
+void TTYSCRN::addedge(const int sym)
+{
+    int nsym;
+#ifdef A_ALTCHARSET
+    if (_acs) {
+       switch (sym) {
+       case GS_HLINE:
+           nsym = ACS_HLINE;
+           break;
+       case GS_VLINE:
+           nsym = ACS_VLINE;
+           break;
+       case GS_ULCORNER:
+           nsym = ACS_ULCORNER;
+           break;
+       case GS_URCORNER:
+           nsym = ACS_URCORNER;
+           break;
+       case GS_LLCORNER:
+           nsym = ACS_LLCORNER;
+           break;
+       case GS_LRCORNER:
+           nsym = ACS_LRCORNER;
+           break;
+       case GS_LTEE:
+           nsym = ACS_LTEE;
+           break;
+       case GS_RTEE:
+           nsym = ACS_RTEE;
+           break;
+       case GS_TTEE:
+           nsym = ACS_TTEE;
+           break;
+       case GS_BTEE:
+           nsym = ACS_BTEE;
+           break;
+       case GS_PLUS:
+           nsym = ACS_PLUS;
+           break;
+       case ' ':
+           addsym(' ');
+           return;
+       default:
+           ::abort();
+       }
+       attron(A_ALTCHARSET);
+       addch(nsym);
+       attroff(A_ALTCHARSET);
+       return;
+    }
+#endif
+    switch (sym) {
+    case GS_HLINE:
+       nsym = '-';
+       break;
+    case GS_VLINE:
+       nsym = '|';
+       break;
+    case GS_ULCORNER:
+       nsym = '.';
+       break;
+    case GS_URCORNER:
+       nsym = '.';
+       break;
+    case GS_LLCORNER:
+       nsym = '.';
+       break;
+    case GS_LRCORNER:
+       nsym = '.';
+       break;
+    case GS_LTEE:
+       nsym = '.';
+       break;
+    case GS_RTEE:
+       nsym = '.';
+       break;
+    case GS_TTEE:
+       nsym = '.';
+       break;
+    case GS_BTEE:
+       nsym = '.';
+       break;
+    case GS_PLUS:
+       nsym = '+';
+       break;
+    case ' ':
+       addsym(' ');
+       return;
+    default:
+       ::abort();
+    }
+    addsym(nsym);
+}
+
+void TTYSCRN::redraw(void)
+{
+    refresh();
+    doupdate();
+}
+
+void TTYSCRN::bell(void)
+{
+    putc('\007', stdout);
+}
+
+int TTYSCRN::getinput(void)
+{
+    return getch();
+}
+
+void TTYSCRN::score(size_t s, const PLAYER& p)
+{
+    mvwprintw(stdscr, _sy + s + TTYSCRN::offsscore, _sx, "S %c:%5d", p.getWho(),
+             p.getScore());
+}
+
+void TTYSCRN::total(size_t s, const PLAYER& p)
+{
+    mvwprintw(stdscr, _sy + s + TTYSCRN::offstotal, _sx, "T %c:%5d", p.getWho(),
+             p.getTotal());
+}
+
+void TTYSCRN::games(size_t s, const PLAYER& p)
+{
+    mvwprintw(stdscr, _sy + s + TTYSCRN::offsgames, _sx, "G %c:%5d", p.getWho(),
+             p.getGames());
+}
+
+void TTYSCRN::ties(const PLAYER& p)
+{
+    mvwprintw(stdscr, _sy + TTYSCRN::offsties, _sx, "G =:%5d", p.getTies());
+}
+
+TTYSCRN* TTYSCRN::create(int acs, size_t y, size_t x)
+{
+    int tx, ty;
+
+    initscr();
+
+    tx = getmaxx(stdscr);
+    ty = getmaxy(stdscr);
+
+    if (tx == ERR || ty == ERR || (size_t)tx < x * 2 + TTYSCRN::offsx + 12
+       || (size_t)ty < y * 2 + TTYSCRN::offsy) {
+       endwin();
+       return NULL;
+    }
+    cbreak();
+    noecho();
+
+
+    TTYSCRN* that = new TTYSCRN;
+
+    that->_tx = tx;
+    that->_ty = ty;
+    that->_sx = tx - 12;
+    that->_sy = TTYSCRN::offsy;
+    that->_acs = acs;
+
+    return that;
+}
+
+TTYSCRN::~TTYSCRN(void)
+{
+    nocbreak();
+    echo();
+    endwin();
+}
diff --git a/dab/ttyscrn.h b/dab/ttyscrn.h
new file mode 100644 (file)
index 0000000..245390a
--- /dev/null
@@ -0,0 +1,80 @@
+/*     $NetBSD: ttyscrn.h,v 1.1.1.1 2003/12/26 17:57:04 christos Exp $ */
+/*-
+ * Copyright (c) 2003 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Christos Zoulas.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *        This product includes software developed by the NetBSD
+ *        Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * ttyscrn.h: Curses based screen for dots
+ */
+
+#ifndef _H_TTYSCRN
+#define _H_TTYSCRN
+
+#include "gamescreen.h"
+
+class TTYSCRN : public GAMESCREEN {
+  public:
+    // Constructor that can fail
+    static TTYSCRN*  create(int acs, size_t y, size_t x);
+    ~TTYSCRN();
+
+    // Screen virtuals
+    void clean(void);
+    void moveto(size_t y, size_t x);
+    void addsym(const int sym);
+    void addedge(const int sym);
+    void redraw(void);
+    void bell(void);
+    int getinput(void);
+    void score(size_t s, const PLAYER& p);
+    void games(size_t s, const PLAYER& p);
+    void total(size_t s, const PLAYER& p);
+    void ties(const PLAYER& p);
+
+  private:
+    enum {
+       offsx = 2,      // board x offset from top left corner
+       offsy = 2,      // board y offset from top left corner
+       offsscore = 0,  // score y offset from top of the board
+       offstotal = 3,  // total y offset from top of the board
+       offsgames = 6,  // games y offset from top of the board
+       offsties = 8    // ties y offset from top of the board
+    };
+    size_t _sx, _sy;   // board size
+    size_t _tx, _ty;   // tty size
+    int _acs;          // do we want acs?
+};
+
+#endif