home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 January
/
usenetsourcesnewsgroupsinfomagicjanuary1994.iso
/
sources
/
games
/
volume13
/
x4war2
/
part01
/
war.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-08-03
|
22KB
|
957 lines
#include "war.h"
extern Arr arr[4][6][5], mid[3][3];
extern Sapper_path sap[];
extern int round;
/*******************************************************************
*
* Synopsis
* fatal_error(s)
* char *s;
*
* Description
* it prints s as an error message and exit.
*
*******************************************************************/
fatal_error(s)
char *s;
{
printf("%s\n", s);
exit(-1);
}
/****************************************************************
*
* Synopsis
* syntax(s)
* char *s;
*
* Argument
* s the program name, usually x4war;
*
* Description
* x4war command line arguments specification
*
****************************************************************/
syntax(s)
char *s;
{
printf("Usage: %s [options ...]\n\n", s);
printf("where options include:\n");
printf("\t-p0 string\t\tplayer0's name\n");
printf("\t-d0 string\t\tplayer0's display\n");
printf("\t-c0 string\t\tplayer0's node color\n");
printf("\t-p1 string\t\tplayer1's name\n");
printf("\t-d1 string\t\tplayer1's display\n");
printf("\t-c1 string\t\tplayer1's node color\n");
printf("\t-p2 string\t\tplayer2's name\n");
printf("\t-d2 string\t\tplayer2's display\n");
printf("\t-c2 string\t\tplayer2's node color\n");
printf("\t-p3 string\t\tplayer3's name\n");
printf("\t-d3 string\t\tplayer3's display\n");
printf("\t-c3 string\t\tplayer3's node color\n");
printf("\t-two \t\t\tplay a two players game\n");
printf("\t-debug\t\t\ta default deploy\n");
printf("\t-usage\t\t\tthis usage list\n");
printf("\t-help\t\t\tthis usage list\n\n");
}
/***********************************************************************
*
* Synopsis
* int fight(x, y)
* int x, y;
*
* Arguments
* x, y representing two node values between COLOURS and BOMB.
* x must be a movable, i.e., not COLOURS and MINE.
*
* Return values
* x < y: return 2;
* x = y: return 3;
* x > y: return 4;
*
* Description
* it returns the fighting result when node x moved to meet node y.
*
***********************************************************************/
int fight(x, y)
int x, y;
{
if (x==SAPPER && y==MINE) return(4);
if (x==BOMB || y==BOMB) return(3);
if (x==y) return(3);
if (x<y) return(2);
if (x>y) return(4);
}
/**********************************************************************
*
* Synopsis
* int boardtofield(x, y, i, j)
* int x, y;
* int *i, *j; return values
*
* Arguments
* x, y coordinates of a point on board;
* *i, *j contain the converted field coordinates;
*
* Return values
* return a value from F0 to OTHERPLACE according to the position (x,y),
* i and j are set if returned values between F0 and RIP.
*
***********************************************************************/
int boardtofield(x, y, i, j)
int x, y, *i, *j;
{
if (x>=315 && x<=555 && y>=565 && y<=855) {
*j = (x-310)/50;
*i = (y-560)/50;
return(F0);
}
if (x>=565 && x<=855 && y>=315 && y<=555) {
*i = (x-560)/50;
*j = 4-(y-310)/50;
return(F1);
}
if (x>=315 && x<=555 && y>=15 && y<=305) {
*i = 5-(y-10)/50;
*j = 4-(x-310)/50;
return(F2);
}
if (x>=15 && x<=305 && y>=315 && y<=555) {
*i = 5-(x-10)/50;
*j = (y-310)/50;
return(F3);
}
if (x>=315 && x<=555 && y>=315 && y<=555) {
*j = (x-310)/100;
*i = (y-310)/100;
return(MIDFIELD);
}
if (x>=35 && x<=285 && y>=585 && y<=835) {
*j = (x-35)/50;
*i = (y-585)/50;
return(RIP);
}
if (x>=BUTTON_X && x<=BUTTON_X + BUTTON_WIDTH) {
if (y>=610 && y<=635) return(NEW);
if (y>=650 && y<=675) return(READY);
if (y>=690 && y<=715) return(REDEPLOY);
if (y>=730 && y<=755) return(PEACE);
if (y>=770 && y<=795) return(SURRENDER);
if (y>=810 && y<=835) return(QUIT);
}
return(OTHERPLACE);
}
/********************************************************************
*
* Synopsis
* fieldtoboard(f, i, j, x, y)
* int f, i, j;
* int *x, *y; return
*
* Arguments
* f field id between F0 and RIP;
* i, j coordinates of the field;
* *x, *y contains returned values of coordinates of the board;
*
*********************************************************************/
fieldtoboard(f, i, j, x, y)
int f, i, j, *x, *y;
{
switch (f) {
case F0:
*x = 335+j*50;
*y = 585+i*50;
break;
case F1:
*x = 585+i*50;
*y = 335+(4-j)*50;
break;
case F2:
*x = 335+(4-j)*50;
*y = 35+(5-i)*50;
break;
case F3:
*x = 35+(5-i)*50;
*y = 335+j*50;
break;
case MIDFIELD:
*x = 335+j*100;
*y = 335+i*100;
break;
case RIP:
*x = 60+j*50;
*y = 610+i*50;
}
}
/**********************************************************************
*
* Synopsis
* arrtoboard(id, g, i, j, x, y)
* int id, g, i, j;
* int *x, *y; return
*
* Arguments
* id 0-3, specifies the player of the board;
* g F0 - RIP, which array;
* i, j coordinates of the array;
* *x, *y contains the results;
*
**********************************************************************/
arrtoboard(id, g, i, j, x, y)
int id, g, i, j, *x, *y;
{
int k;
if (g==MIDFIELD)
switch (id) {
case 1:
k = i; i = j; j = 2-k;
break;
case 2:
i = 2-i; j = 2-j;
break;
case 3:
k = i; i = 2-j; j = k;
}
else if (g != RIP) {
g -= id;
if (g<0) g += 4;
}
fieldtoboard(g,i,j,x,y);
}
/*********************************************************************
*
* Synopsis
* int fieldtoarr(id, f, fi, fj, ai, aj)
* int id, f, fi, fj;
* int *ai, *aj;
*
* Arguments
* id 0-3, the player of the board;
* f F0 - RIP, field number;
* fi, fj coordinates in the field;
* *ai, *aj result coordinates of the array;
*
* Return value
* returns which array is resulted
*
**********************************************************************/
int fieldtoarr(id, f, fi, fj, ai, aj)
int id, f, fi, fj, *ai, *aj;
{
*ai = fi;
*aj = fj;
if ( f==MIDFIELD )
switch (id) {
case 1:
*ai = 2-fj; *aj = fi;
break;
case 2:
*ai = 2 - fi; *aj = 2 - fj;
break;
case 3:
*ai = fj; *aj = 2 - fi;
}
return((f>=F0 && f<MIDFIELD) ? (f+id)%4 : f);
}
/*********************************************************************
*
* Synopsis
* int boardtoarr(f, x, y, i, j)
* int f, x, y, *i, *j;
*
* Arguments
* f specifies who's board;
* x, y the coordinates on board;
* *i, *j return the coordinates in the array;
*
* Return value
* it returns which array the point corresponds.
* returns -1 if no array to match.
*
**********************************************************************/
int boardtoarr(f, x, y, i, j)
int f, x, y, *i, *j;
{
int m, n, s;
s = boardtofield(x, y, &m, &n);
if (s > RIP) return(-1);
s = fieldtoarr(f, s, m, n, i, j);
return(s);
}
/************************************************************************
*
* Synopsis
* int area_intersection(ax1, ay1, ax2, ay2, bx1, by1, bx2, by2,
* cx1, cy1, cx2, cy2)
* int ax1, ay1, ax2, ay2, bx1, by1, bx2, by2;
* int *cx1, *cy1, *cx2, *cy2; return
*
* Arguments
* a's and b's: coordinates of two rectangles;
* c's contains the coordinates of the intersection area;
*
* Return values
* 1 if the two rectangles intersect, and c's are set;
* 0 if the two rectangles not intersect;
*
**************************************************************************/
int area_intersection(ax1, ay1, ax2, ay2, bx1, by1, bx2, by2,
cx1, cy1, cx2, cy2)
int ax1, ay1, ax2, ay2, bx1, by1, bx2, by2, *cx1, *cy1, *cx2, *cy2;
{
int k;
if (ax1>ax2) {
k = ax1; ax1 = ax2; ax2 = k;
}
if (ay1>ay2) {
k = ay1; ay1 = ay2; ay2 = k;
}
if (bx1>bx2) {
k = bx1; bx1 = bx2; bx2 = k;
}
if (by1>by2) {
k = by1; by1 = by2; by2 = k;
}
*cx2 = (ax2<bx2) ? ax2 : bx2;
*cy2 = (ay2<by2) ? ay2 : by2;
if (ax1<=bx1 && ay1<=by1 && bx1<ax2 && by1<ay2) {
*cx1 = bx1; *cy1 = by1;
return(1);
}
if (ax1<=bx1 && ay1>by1 && ay1<by2 && ax2>bx1) {
*cx1 = bx1; *cy1 = ay1;
return(1);
}
if (ax1>bx1 && ay1>by1 && ax1<bx2 && ay1<by2) {
*cx1 = ax1; *cy1 = ay1;
return(1);
}
if (ax1>bx1 && ay1<by1 && ax1<bx2 && ay2>by1) {
*cx1 = ax1; *cy1 = by1;
return(1);
}
return(0);
}
/**********************************************************************
*
* Synopsis
* int sapper_check(i, x, y, z)
* int i, x, y, z;
*
* Arguments
* i start check from i of sap[];
* x, y, z the destination;
*
* Return values
* 0 if cannot reach destination;
* 1 if can reach destination;
*
* Side effect
* mark all visited nodes to round.
*
* Description
* it recursively checks if a SAPPER can reach a destination, starting
* from a position in sap[i]; sap[i] must not have been visited, and
* the starting position must not be the destination.
*
***********************************************************************/
int sapper_check(i, x, y, z)
int i, x, y, z;
{
int m, n, a, b, c, j;
sap[i].visited = round;
m = 0;
if (i<12) {
a = i/3;
c = 2*(i%3);
if (c==0) {
n = (a-1);
if (n<0) n = 3;
if (y==0 && z==4 && x==n) return(1);
if (sap[n*3+2].visited != round && arr[n][0][4].value == EMPTY)
m = sapper_check(n*3+2, x, y, z);
if (m) return(1);
n = sap[i].neighbor[0];
b = (n-12)/3;
c = (n-12)%3;
if (x==MIDFIELD && y==b && z==c) return(1);
if (sap[n].visited != round && mid[b][c].value == EMPTY)
m = sapper_check(n, x, y, z);
if (m) return(1);
if (x==a && y==0 && z==1) return(1);
if (arr[a][0][1].value == EMPTY) {
if (x==a && y==0 && z==2) return(1);
if (sap[a*3+1].visited != round && arr[a][0][2].value == EMPTY)
m = sapper_check(a*3+1, x, y, z);
if (m) return(1);
}
if (a==x || sap[a*3+2].visited != round) {
if (a==x && z==0) {
for (j=1; j<y; j++)
if (arr[a][j][0].value != EMPTY) return(0);
return(1);
}
for (j=1; j<5; j++)
if (arr[a][j][0].value != EMPTY) return(0);
if (a==x && y==4) {
for (j=1; j<z; j++)
if (arr[a][4][j].value != EMPTY) return(0);
return(1);
}
for (j=1; j<5; j++)
if (arr[a][4][j].value != EMPTY) return(0);
if (a==x && z==4) {
for (j=y+1; j<4; j++)
if (arr[a][j][4].value != EMPTY) return(0);
return(1);
}
if (sap[a*3+2].visited == round) return(0);
for (j=0; j<4; j++)
if (arr[a][j][4].value != EMPTY) return(0);
return(sapper_check(a*3+2, x, y, z));
}
return(0);
}
if (c==2) {
if (a==x && y==0 && z==1) return(1);
if (arr[a][0][1].value == EMPTY) {
if (a==x && y==0 && z==0) return(1);
if (sap[a*3].visited != round && arr[a][0][0].value == EMPTY)
m = sapper_check(a*3, x, y, z);
if (m) return(1);
}
n = sap[i].neighbor[0];
b = (n-12)/3;
c = (n-12)%3;
if (x==MIDFIELD && y==b && z==c) return(1);
if (sap[n].visited != round && mid[b][c].value == EMPTY)
m = sapper_check(n, x, y, z);
if (m) return(1);
if (a==x && y==0 && z==3) return(1);
if (arr[a][0][3].value == EMPTY) {
if (a==x && y==0 && z==4) return(1);
if (sap[a*3+2].visited != round && arr[a][0][4].value == EMPTY)
m = sapper_check(a*3+2, x, y, z);
if (m) return(1);
}
return(0);
}
/* now c==4 */
if (a==x && y==0 && z==3) return(1);
if (arr[a][0][3].value == EMPTY) {
if (a==x && y==0 && z==2) return(1);
if (sap[a*3+1].visited != round && arr[a][0][2].value == EMPTY)
m = sapper_check(a*3+1, x, y, z);
if (m) return(1);
}
n = sap[i].neighbor[0];
b = (n-12)/3;
c = (n-12)%3;
if (x==MIDFIELD && b==y && c==z) return(1);
if (sap[n].visited != round && mid[b][c].value == EMPTY)
m = sapper_check(n, x, y, z);
if (m) return(1);
n = (a+1)%4;
if (x==n && y==0 && z==0) return(1);
if (sap[n*3].visited != round && arr[n][0][0].value == EMPTY)
m = sapper_check(n*3, x, y, z);
if (m) return(1);
if (sap[a*3].visited != round || a==x) {
if (a==x && z==4) {
for (j=1; j<y; j++)
if (arr[a][j][4].value != EMPTY) return(0);
return(1);
}
for (j=1; j<5; j++)
if (arr[a][j][4].value != EMPTY) return(0);
if (a==x && y==4) {
for (j=z+1; j<4; j++)
if (arr[a][4][j].value != EMPTY) return(0);
return(1);
}
for (j=0; j<4; j++)
if (arr[a][4][j].value != EMPTY) return(0);
if (a==x && z==0) {
for (j=y+1; j<4; j++)
if (arr[a][j][0].value != EMPTY) return(0);
return(1);
}
if (sap[a*3].visited == round) return(0);
for (j=0; j<4; j++)
if (arr[a][j][0].value != EMPTY) return(0);
return(sapper_check(a*3, x, y, z));
}
return(0);
}
else { /* starting position in the MIDFIELD */
j = 0;
while (!m && j<4) {
n = sap[i].neighbor[j];
if (sap[n].visited != round)
if (n<12) {
a = n/3;
c = 2*(n%3);
if (x==a && y==0 && z==c) return(1);
if (arr[a][0][c].value == EMPTY)
m = sapper_check(n, x, y, z);
}
else {
b = (n-12)/3;
c = (n-12)%3;
if (x==MIDFIELD && y==b && z==c) return(1);
if (mid[b][c].value == EMPTY)
m = sapper_check(n, x, y, z);
}
j++;
}
return(m);
}
}
/**********************************************************************
*
* Synopsis
* int valid_move(a, b, c, x, y, z)
* int a, b, c, x, y, z;
*
* Return values
* 1 for valid move;
* 0 for invalid move;
*
* Description
* It checks if a move as (a,b,c)=>(x,y,z) is valid according to
* the positions;
*
***********************************************************************/
int valid_move(a, b, c, x, y, z)
int a, b, c, x, y, z;
{
int m, n, i, l;
if ((a<MIDFIELD && x<MIDFIELD) && (b==5 || y==5 ||
(0<b && b<4 && 0<c && c<4) || (0<y && y<4 && 0<z && z<4))) {
/* can move only one step far */
if (a != x) return(0);
m = abs(b-y) + abs(c-z);
if (m<1 || m>2) return(0);
if ( (abs(b-y)<2 && abs(c-z)<2) &&
(((b==1 || b==3) && (c==1 || c==3)) || (b==2 && c==2) ||
((y==1 || y==3) && (z==1 || z==3)) || (y==2 && z==2)))
return(1);
if (m == 1) return(1);
else return(0);
}
/* from now on, the source and the destination are both on the railway */
if (a==MIDFIELD && mid[b][c].value == SAPPER ||
a<MIDFIELD && arr[a][b][c].value == SAPPER) {
round++;
m = 0;
if (a<MIDFIELD && (b!=0 || (b==0 && (c==1 || c==3)))) {
if (b==0)
if (c==1) {
if (x==a && y==0 && (z==0 || z==2)) return(1);
if (arr[a][0][0].value == EMPTY)
m = sapper_check(a*3, x, y, z);
if (m) return(1);
if (sap[a*3+1].visited!=round && arr[a][0][2].value==EMPTY)
m = sapper_check(a*3+1, x, y, z);
return(m);
}
else {
if (x==a && y==0 && (z==2 || z==4)) return(1);
if (arr[a][0][2].value != EMPTY)
m = sapper_check(a*3+1, x, y, z);
if (m) return(1);
if (sap[a*3+2].visited!=round && arr[a][0][4].value==EMPTY)
m = sapper_check(a*3+2, x, y, z);
return(m);
}
else
if (c==0 || c==4) {
if (a==x && z==c && y<b) {
for (i=y+1; i<b; i++)
if (arr[a][i][c].value != EMPTY) break;
if (i==b) return(1);
}
else {
for (i=0; i<b; i++)
if (arr[a][i][c].value != EMPTY) break;
if (i==b)
m = sapper_check(a*3+(c/2), x, y, z);
if (m) return(1);
}
if (a==x || sap[a*3].visited != round ||
sap[a*3+2].visited != round) {
if (a==x && z==c && y>b) {
for (i=b+1; i<y; i++)
if (arr[a][i][c].value != EMPTY) return(0);
return(1);
}
for (i=b+1; i<5; i++)
if (arr[a][i][c].value != EMPTY) return(0);
if (a==x && y==4)
if (c==0) {
for (i=1; i<z; i++)
if (arr[a][4][i].value != EMPTY) return(0);
return(1);
}
else {
for (i=z+1; i<4; i++)
if (arr[a][4][i].value != EMPTY) return(0);
return(1);
}
n = (c==0) ? 1 : 0;
for (i=0; i<4; i++)
if (arr[a][4][i+n].value != EMPTY) return(0);
n = (c==0) ? 4 : 0;
if (a==x && n==z) {
for (i=y+1; i<4; i++)
if (arr[a][i][n].value != EMPTY) return(0);
return(1);
}
if (sap[a*3+n/2].visited == round) return(0);
for (i=0; i<4; i++)
if (arr[a][i][n].value != EMPTY) return(0);
return(sapper_check(a*3+n/2, x, y, z));
}
return(0);
}
else { /* starting point is at the second bottom line */
if (a==x && y==4 && z<c) {
for (i=z+1; i<c; i++)
if (arr[a][4][i].value != EMPTY) break;
if (i==c) return(1);
}
else
for (i=0; i<c; i++)
if (arr[a][4][i].value != EMPTY) break;
if (i==c) {
if (a==x && y<4 && z==0) {
for (i=y+1; i<4; i++)
if (arr[a][i][0].value != EMPTY) break;
if (i==4) return(1);
}
else
for (i=0; i<4; i++)
if (arr[a][i][0].value != EMPTY) break;
if (i==4) {
m = sapper_check(a*3, x, y, z);
if (m) return(1);
}
}
if (a==x || sap[a*3].visited != round ||
sap[a*3+2].visited != round) {
if (a==x && y==4 && z>c) {
for (i=c+1; i<z; i++)
if (arr[a][4][i].value != EMPTY) return(0);
return(1);
}
for (i=c+1; i<5; i++)
if (arr[a][4][i].value != EMPTY) return(0);
if (a==x && y<4 && z==4) {
for (i=y+1; i<4; i++)
if (arr[a][i][4].value != EMPTY) return(0);
return(1);
}
if (sap[a*3+2].visited==round) return(0);
for (i=0; i<4; i++)
if (arr[a][i][4].value != EMPTY) return(0);
return(sapper_check(a*3+2, x, y, z));
}
return(0);
}
}
else
if (a<4) return(sapper_check(a*3+c/2, x, y, z));
else return(sapper_check(12+b*3+c, x, y, z));
}
/* now the moving node is not a SAPPER */
if (a<MIDFIELD && a==x) {
if (b==y && (b==0 || b==4)) {
if (c < z) {
m = c; n = z;
}
else {
m = z; n = c;
}
for (i=m+1; i<n; i++)
if (arr[a][b][i].value != EMPTY) return(0);
return(1);
}
else if (c==z && (c==0 || c==4)) {
if (b < y) {
m = b; n = y;
}
else {
m = y; n = b;
}
for (i=m+1; i<n; i++)
if (arr[a][i][c].value != EMPTY) return(0);
return(1);
}
else return(0);
}
/* from now on the source and the destination are on different fields */
if (a != MIDFIELD)
if (c==0 || c==4) {
for (i=0; i<b; i++)
if (arr[a][i][c].value != EMPTY) return(0);
}
else
if (b!=0 || c!=2) return(0);
if (x != MIDFIELD)
if (z==0 || z==4) {
for (i=0; i<y; i++)
if (arr[x][i][z].value != EMPTY) return(0);
}
else
if (y!=0 || z!=2) return(0);
if (a<MIDFIELD && x<MIDFIELD) {
if ((x+1)%4 == a)
if (z==4 && c==0) return(1);
else return(0);
else if ((a+1)%4 == x)
if (z==0 && c==4) return(1);
else return(0);
if (!((c==0 && z==4) || (c==4 && z==0) || (c==2 && z==2)))
return(0);
}
/* now the move has to go across the MIDFIELD */
if ((a<MIDFIELD && a%2==0) || (x<MIDFIELD && x%2==0) ||
(a==MIDFIELD && x==MIDFIELD && c==z)) {
if (a != MIDFIELD) {
if (a==F0) {
l = c/2;
n = 2;
m = (x==MIDFIELD) ? (y+1) : 0;
}
else {
l = (4-c)/2;
m = 0;
n = (x==MIDFIELD) ? (y-1) : 2;
}
if (x==MIDFIELD && l!=z) return(0);
}
else
if (x != MIDFIELD) {
if (x==F0) {
l = z/2;
m = b+1;
n = 2;
}
else {
l = (4-z)/2;
m = 0;
n = b-1;
}
if (l != c) return(0);
}
else {
l = z;
if (b<y) {
m = b+1; n = y-1;
}
else {
m = y+1; n = b-1;
}
}
for (i=m; i<=n; i++)
if (mid[i][l].value != EMPTY) return(0);
return(1);
}
if ((a<MIDFIELD && a%2!=0) || (x<MIDFIELD && x%2!=0) ||
(a==MIDFIELD && x==MIDFIELD && b==y)) {
if (a != MIDFIELD) {
if (a==F1) {
l = (4-c)/2;
n = 2;
m = (x==MIDFIELD) ? (z+1) : 0;
}
else {
l = c/2;
m = 0;
n = (x==MIDFIELD) ? (z-1) : 2;
}
if (x == MIDFIELD && l != y) return(0);
}
else
if (x != MIDFIELD) {
if (x==F1) {
l = (4-z)/2;
m = c+1;
n = 2;
}
else {
l = z/2;
m = 0;
n = c-1;
}
if (l != b) return(0);
}
else {
l = b;
if (c<z) {
m = c+1; n = z-1;
}
else {
m = z+1; n = c-1;
}
}
for (i=m; i<=n; i++)
if (mid[l][i].value != EMPTY) return(0);
return(1);
}
return(0);
}
/*************************************************************************
*
* Synopsis
* initial_sapper()
*
* Description
* initializes the array 'sap' of the sapper move checking path.
*
**************************************************************************/
initial_sapper()
{
int i;
round = 0;
for (i=0; i<21; i++)
sap[i].visited = 0;
sap[0].neighbor[0] = 18;
sap[1].neighbor[0] = 19;
sap[2].neighbor[0] = 20;
sap[3].neighbor[0] = 20;
sap[4].neighbor[0] = 17;
sap[5].neighbor[0] = 14;
sap[6].neighbor[0] = 14;
sap[7].neighbor[0] = 13;
sap[8].neighbor[0] = 12;
sap[9].neighbor[0] = 12;
sap[10].neighbor[0] = 15;
sap[11].neighbor[0] = 18;
sap[12].neighbor[0] = 9;
sap[12].neighbor[1] = 8;
sap[12].neighbor[2] = 13;
sap[12].neighbor[3] = 15;
sap[13].neighbor[0] = 12;
sap[13].neighbor[1] = 7;
sap[13].neighbor[2] = 14;
sap[13].neighbor[3] = 16;
sap[14].neighbor[0] = 13;
sap[14].neighbor[1] = 6;
sap[14].neighbor[2] = 5;
sap[14].neighbor[3] = 17;
sap[15].neighbor[0] = 10;
sap[15].neighbor[1] = 12;
sap[15].neighbor[2] = 16;
sap[15].neighbor[3] = 18;
sap[16].neighbor[0] = 15;
sap[16].neighbor[1] = 13;
sap[16].neighbor[2] = 17;
sap[16].neighbor[3] = 19;
sap[17].neighbor[0] = 16;
sap[17].neighbor[1] = 14;
sap[17].neighbor[2] = 4;
sap[17].neighbor[3] = 20;
sap[18].neighbor[0] = 11;
sap[18].neighbor[1] = 15;
sap[18].neighbor[2] = 19;
sap[18].neighbor[3] = 0;
sap[19].neighbor[0] = 18;
sap[19].neighbor[1] = 16;
sap[19].neighbor[2] = 20;
sap[19].neighbor[3] = 1;
sap[20].neighbor[0] = 19;
sap[20].neighbor[1] = 17;
sap[20].neighbor[2] = 3;
sap[20].neighbor[3] = 2;
}