File: triboard.cc

package info (click to toggle)
atom4 4.1-6
  • links: PTS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 656 kB
  • ctags: 947
  • sloc: cpp: 4,461; makefile: 54; sh: 21; perl: 6
file content (127 lines) | stat: -rw-r--r-- 2,808 bytes parent folder | download | duplicates (7)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
/*
 * Generic triangular board representation
 * Implementation file
 * ---------------------------------------------------------------------------
 * $Id: triboard.cc,v 1.6 2003/03/17 16:48:23 hsteoh Exp hsteoh $
 */

#include <assert.h>
#include "triboard.h"


void triboard::copy(triboard &b) {
  wd=b.wd, ht=b.ht;
  ox=b.ox, oy=b.oy;

  board = new celltype[wd*ht];
  for (int y=0; y<ht; y++)
    for (int x=0; x<wd; x++)
      board[y*wd + x] = b.getcell(x,y);

  cells_left = b.cells_left;
}

triboard::triboard(unsigned int width, unsigned int height) {
  int i,j;

  ox=oy=0;				// for now

  assert(width>0 && height>0);
  wd = width;
  ht = height;

  // Allocate board
  board = new celltype[wd*ht];
  assert(board);
  clear();				// start with empty board
}

triboard &triboard::operator= (triboard &b) {
  delete [] board;
  copy(b);
  return *this;
}

triboard::~triboard() {
  delete [] board;
}

celltype triboard::getcell(int x, int y) {
  x += ox;				// convert to absolute board coors
  y += oy;

  if (x<0 || x>=wd || y<0 || y>=ht) {
    return BAD_CELL;			// no such cell
  } else {
    return board[y*wd + x];
  }
}

void triboard::setcell(int x, int y, celltype cell) {
  x += ox;
  y += oy;

  if (x>=0 && x<wd && y>=0 && y<ht) {
    celltype oldcell = board[y*wd + x];

    board[y*wd + x] = cell;
    if (oldcell==EMPTY_CELL && cell!=EMPTY_CELL)
      cells_left--;
    else if (oldcell!=EMPTY_CELL && cell==EMPTY_CELL)
      cells_left++;
  } // else { Probably want to throw exception }
}

celltype triboard::ngbr_of(int x, int y, int dir) {
  int nx, ny;

  if (!ngbr_coor(x,y,dir,nx,ny))	// calculate neighbour's coordinates
    return BAD_CELL;			// bad cell specified
  else
    return board[ny*wd + nx];
}

// Calculate neighbour's coordinates given (x,y) and a direction.
// Returns true if OK, false if bad parameters
int triboard::ngbr_coor(int x, int y, int dir, int &nx, int &ny) {
  x += ox;
  y += oy;
  if (x<0 || x>=wd || y<0 || y>=ht || dir<0 || dir>=6)
    return 0;

  switch(dir) {
  case 0:	nx = x-1 + (y%2);	ny = y-1;	break;
  case 1:	nx = x + (y%2);		ny = y-1;	break;
  case 2:	nx = x+1;		ny = y;		break;
  case 3:	nx = x + (y%2);		ny = y+1;	break;
  case 4:	nx = x-1 + (y%2);	ny = y+1;	break;
  case 5:	nx = x-1;		ny = y;		break;
  default:	return 0;
  }

  // Make sure resulting coors are actually legal
  return (nx>=0 && nx<wd && ny>=0 && ny<ht);
}

void triboard::mapcell(void (*f)(int x, int y, celltype cell, void *context),
                       void *context) {
  unsigned int i, j;

  for (j=0; j<ht; j++) {
    for (i=0; i<wd; i++) {
      f(i, j, board[j*wd + i], context);
    }
  }
}

void triboard::clear() {
  int i,j;

  for (j=0; j<ht; j++) {
    for (i=0; i<wd; i++) {
      board[j*wd + i] = EMPTY_CELL;
    }
  }
  cells_left=wd*ht;
}