(linenum→info "unix/slp.c:2238")

bsd-games/2.17/dab/board.cc

    1: /*      $NetBSD: board.cc,v 1.1 2003/12/27 01:16:55 christos Exp $   */
    2: 
    3: /*-
    4:  * Copyright (c) 2003 The NetBSD Foundation, Inc.
    5:  * All rights reserved.
    6:  *
    7:  * This code is derived from software contributed to The NetBSD Foundation
    8:  * by Christos Zoulas.
    9:  *
   10:  * Redistribution and use in source and binary forms, with or without
   11:  * modification, are permitted provided that the following conditions
   12:  * are met:
   13:  * 1. Redistributions of source code must retain the above copyright
   14:  *    notice, this list of conditions and the following disclaimer.
   15:  * 2. Redistributions in binary form must reproduce the above copyright
   16:  *    notice, this list of conditions and the following disclaimer in the
   17:  *    documentation and/or other materials provided with the distribution.
   18:  * 3. All advertising materials mentioning features or use of this software
   19:  *    must display the following acknowledgement:
   20:  *        This product includes software developed by the NetBSD
   21:  *        Foundation, Inc. and its contributors.
   22:  * 4. Neither the name of The NetBSD Foundation nor the names of its
   23:  *    contributors may be used to endorse or promote products derived
   24:  *    from this software without specific prior written permission.
   25:  *
   26:  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
   27:  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   28:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   29:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   30:  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   31:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   32:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   33:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   34:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   35:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   36:  * POSSIBILITY OF SUCH DAMAGE.
   37:  */
   38: 
   39: /*
   40:  * board.C: Board manipulations
   41:  */
   42: #include "defs.h"
   43: RCSID("$NetBSD: board.cc,v 1.1 2003/12/27 01:16:55 christos Exp $")
   44: 
   45: #include <stdio.h>
   46: #include <string.h>
   47: #include <stdarg.h>
   48: #include "board.h"
   49: #include "gamescreen.h"
   50: #include "box.h"
   51: #include "player.h"
   52: 
   53: BOARD::BOARD(size_t y, size_t x, GAMESCREEN* scrn) :
   54:     _ny(y),
   55:     _nx(x),
   56:     _scrn(scrn)
   57: {
   58:     _ty = 2 * _ny + 1;
   59:     _tx = 2 * _nx + 1;
   60: 
   61:     _b = new int*[_ty];
   62: 
   63:     for (y = 0; y < _ty; y++)
   64:         _b[y] = new int[_tx];
   65: 
   66:     init();
   67: }
   68: 
   69: BOARD::BOARD(const BOARD& b) :
   70:     _ty(b._ty),
   71:     _tx(b._tx),
   72:     _ny(b._ny),
   73:     _nx(b._nx),
   74:     _scrn(NULL)
   75: {
   76:     _b = new int*[_ty];
   77: 
   78:     for (size_t y = 0; y < _ty; y++) {
   79:         _b[y] = new int[_tx];
   80:         (void) memcpy(_b[y], b._b[y], _tx * sizeof(int));
   81:     }
   82: }
   83: 
   84: BOARD::~BOARD()
   85: {
   86:     size_t y;
   87: 
   88:     for (y = 0; y < _ty; y++)
   89:         delete[] _b[y];
   90: 
   91:     delete[] _b;
   92: }
   93: 
   94: // Clear all boxes and reset state for a new game
   95: void BOARD::init(void)
   96: {
   97:     size_t x, y;
   98: 
   99:     for (y = 0; y < _ny; y++) 
  100:         for (x = 0; x < _nx; x++) {
  101:             BOX box(y, x, *this);
  102:             box.reset();
  103:         }
  104: }
  105: 
  106: /*
  107:  * Make a move for player with initial 'c', adding an edge at box(x, y)
  108:  * and the specified direction.
  109:  * returns:
  110:  *      -1:  Invalid move
  111:  *       n:  Number of closures n E [0..2]
  112:  */
  113: int BOARD::domove(size_t y, size_t x, int dir, char c)
  114: {
  115:     int closed = 0;
  116: 
  117:     // Check if out of bounds
  118:     if (!bounds(y, x))
  119:         return -1;
  120: 
  121:     BOX box1(y, x, *this);
  122: 
  123:     // Check if the edge is already there
  124:     if (box1.isset(dir))
  125:         return -1;
  126: 
  127:     box1.set(dir);
  128: 
  129:     if (box1.count() == 4) {
  130:         // New box; name it and count it
  131:         box1.name() = c;
  132:         closed++;
  133:     }
  134: 
  135:     box1.paint();
  136: 
  137:     // Check other box
  138:     x += BOX::edges[dir].x;
  139:     y += BOX::edges[dir].y;
  140: 
  141:     if (bounds(y, x)) {
  142:         BOX box2(y, x, *this);
  143:         if (box2.count() == 4) {
  144:             box2.name() = c;
  145:             box2.paint();
  146:             closed++;
  147:         }
  148:     }
  149:     return closed;
  150: }
  151: 
  152: // Return true if the board is full
  153: int BOARD::full(void) const
  154: {
  155:     for (size_t y = 0; y < _ny; y++)
  156:         for (size_t x = 0; x < _nx; x++) {
  157:             BOX box(y, x, (BOARD&) *this);
  158:             if (box.count() != 4)
  159:                 return 0;
  160:         }
  161:     return 1;
  162: }
  163: 
  164: // Return if the coordinates are within bounds; we don't check for < 0,
  165: // since size_t is unsigned
  166: int BOARD::bounds(size_t y, size_t x) const
  167: {
  168:     return x < _nx && y < _ny;
  169: }
  170: 
  171: // Paint all boxes, effectively redrawing the board
  172: void BOARD::paint(void) const
  173: {
  174:     for (size_t y = 0; y < _ny; y++)
  175:         for (size_t x = 0; x < _nx; x++) {
  176:             BOX box(y, x, (BOARD&) *this);
  177:             box.paint();
  178:         }
  179: }
  180: 
  181: // Clear the screen
  182: void BOARD::clean(void) const
  183: {
  184:     if (!_scrn)
  185:         return;
  186:     _scrn->clean();
  187: }
  188: 
  189: // Move cursor to x, y
  190: void BOARD::setpos(size_t y, size_t x) const
  191: {
  192:     if (!_scrn)
  193:         return;
  194:     _scrn->moveto(y, x);
  195:     _scrn->redraw();
  196: }
  197: 
  198: // Return character indicating move
  199: int BOARD::getmove(void) const
  200: {
  201:     if (!_scrn)
  202:         return 'q';
  203:     _scrn->redraw();
  204:     return _scrn->getinput();
  205: }
  206: 
  207: // Ring the bell
  208: void BOARD::bell(void) const
  209: {
  210:     if (!_scrn)
  211:         return;
  212:     _scrn->bell();
  213: }
  214: 
  215: // Post the score in the current game for player i
  216: void BOARD::score(size_t i, const PLAYER& p)
  217: {
  218:     if (_scrn == NULL)
  219:         return;
  220:     _scrn->score(i, p);
  221: }
  222: 
  223: // Post the number of games won for player i
  224: void BOARD::games(size_t i, const PLAYER& p)
  225: {
  226:     if (_scrn == NULL)
  227:         return;
  228:     _scrn->games(i, p);
  229: }
  230: 
  231: // Post the total score for player i
  232: void BOARD::total(size_t i, const PLAYER& p)
  233: {
  234:     if (_scrn == NULL)
  235:         return;
  236:     _scrn->total(i, p);
  237: }
  238: 
  239: // Post the total score for player i
  240: void BOARD::ties(const PLAYER& p)
  241: {
  242:     if (_scrn == NULL)
  243:         return;
  244:     _scrn->ties(p);
  245: }
  246: 
  247: // Internal algorithm error; post and abort
  248: void BOARD::abort(const char* s, ...) const
  249: {
  250:     for (size_t i = 0; i < _ny; i++)
  251:         fprintf(stderr, "\n");
  252: 
  253:     va_list ap;
  254:     fprintf(stderr, "Algorithm internal error: ");
  255:     va_start(ap, s);
  256:     vfprintf(stderr, s, ap);
  257:     va_end(ap);
  258:     fprintf(stderr, "\n");
  259:     ::abort();
  260: }
Syntax (Markdown)