*/
Got something to write about? Check out our Article Builder.
*/

View \LIST.C

C souce code for the game of Go

Submitted By: WEBMASTER
Rating: starstarstarhalf star (Rate It)


#include <dos.h>
#include <conio.h>
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <time.h>
#include <stdio.h>
#include <alloc.h>
#include <graphics.h>
#define EXTCDECL extern
#include "goh.c"

/* function prototypes necessary for farcoreleft, farmalloc */
unsigned long farcoreleft(void);
void far *farmalloc(unsigned long nbytes);
void farfree(void far *block);

void initsmall()
{
 unsigned i;
 char *ptr;
 allomax = 0;
 /* allow 4000 extra bytes */
 amount = coreleft()-6400; /* was ok at 4000 ... !!! stack hits here !!! */
 if (nsize <= 9) amount = coreleft() / 2;
 ptr = malloc(amount);
 first = (unsigned *) ptr;
 ptr += amount;
 last = (unsigned *) ptr;
 printf("\n initsmall: first last %u %u \n", first, last);
 ptr = (char *) first;
 do {
  ptr += SMALL + 4;
  ++allomax;
 } while (ptr <= (char *) last);
 --allomax;
 avail = first;
 first += allomax;
 ++first;
 lastused = avail;
 for (i = 1;  i <= allomax;  ++i) {
  *lastused = first;
  ++lastused;
  first += (SMALL / 2 + 1);
 }
 lastused = avail;
 --lastused;
 first = avail;
 npage = 0;
 maxpage = 0;
 pminstk = last;
 minstk = pminstk;
 ++pminstk;
}

unsigned *allosmall()
{
 unsigned *ptr;
 unsigned *temp;
 ++npage;
 if (npage > allomax) {
  newline();
  printf("allosmall fails");
  newline();
  printf(" at %u", npage);
  newline();
  printf(":");
  newline();
  printf("Ctl-c to end");
  getch();
  fix();
  exit(1);
 }
 if (npage > maxpage) {
  maxpage = npage;
 }
 ++lastused;
 ++avail;
 ptr = *lastused;
 temp = ptr;
 --temp;
 *temp = lastused;
 return (ptr);
}

void freesmall(ptr)
unsigned *ptr;
{
 unsigned *temp, *index;
 --npage;
 temp = ptr;
 --temp;
 index = *temp;
 temp = *lastused;
 --temp;
 *temp = index;
 *index = *lastused;
 *lastused = ptr;
 --lastused;
 --avail;
}

void initlarge()
{
 unsigned i;
 char *ptr;
 amtlg = 6000;
 #if DDD
 amtlg = 3400;
 #endif
 almxlg = 0;
 ptr = malloc(amtlg);
 flg = (unsigned *) ptr;
 ptr += amtlg;
 llg = (unsigned *) ptr;
 printf("\n initlarge: flg llg %u %u \n", flg, llg);
 ptr = (char *) flg;
 do {
  ptr += LARGE + 4;
  ++almxlg;
 } while (ptr <= (char *) llg);
 --almxlg;
 avlg = flg;
 flg += almxlg;
 ++flg;
 lastlg = avlg;
 for (i = 1;  i <= almxlg;  ++i) {
  *lastlg = flg;
  ++lastlg;
  flg += (LARGE / 2 + 1);
 }
 lastlg = avlg;
 --lastlg;
 flg = avlg;
 nplg = 0;
 mxlg = 0;
}

unsigned *allolarge()
{
 unsigned *ptr;
 unsigned *temp;
 ++nplg;
 if (nplg > almxlg) {
  newline();
  printf("allolarge fails");
  newline();
  printf(" at %u", nplg);
  newline();
  printf(":");
  newline();
  printf("ctl-c to end");
  getch();
  fix();
  exit(1);
 }
 if (nplg > mxlg) {
  mxlg = nplg;
 }
 ++lastlg;
 ++avlg;
 ptr = *lastlg;
 temp = ptr;
 --temp;
 *temp = lastlg;
 return (ptr);
}

void freelarge(ptr)
unsigned *ptr;
{
 unsigned *temp, *index;
 --nplg;
 temp = ptr;
 --temp;
 index = *temp;
 temp = *lastlg;
 --temp;
 *temp = index;
 *index = *lastlg;
 *lastlg = ptr;
 --lastlg;
 --avlg;
}



void initextra()
{
 unsigned i;
 unsigned long ifar, nbytes;
 unsigned ptr;
 unsigned huh;
 almxxt = 0;
 ifar = farcoreleft();
 printf("\n initextra: farcoreleft:%lu", ifar);
 ifar -= 4500; /* 8192? leave some space on far heap */
 if (nsize <= 9) ifar /= 2;
 amtxt = ifar / 16 - 2;
 farxt = farmalloc(ifar);
 ptr = FP_SEG(farxt);
 i = FP_OFF(farxt)/* check that offset is small */
 ptr += 2;
 ptr += i / 16;     /* allow for offset (should not count) */
 printf("\n xt use %u pages", amtxt);
 printf(" starting at seg %u (off:%u)", ptr, i);
 /*hundelay(200);*/

 fxt = ptr;
 ptr += amtxt;
 lxt = ptr;
 almxxt = (amtxt/8)*7;
 avxt = fxt;
 fxt += amtxt/8;
 ++fxt;
 lastxt = 0;
 for (i = 1;  i <= almxxt;  ++i) {
  poke(avxt, lastxt, fxt);
  poke(fxt,0,lastxt);
  huh = avxt + lastxt/16;
  if((i<5)||(i>almxxt-5))printf("\ninitextra:%5u %6u %6u %6u",i,avxt,huh,fxt);
  lastxt += 2;
  ++fxt;
 }
 lastxt = 0;
 fxt = avxt;
 avxt = 0;
 npxt = 0;
 mxxt=0;
}

unsigned alloextra()
{
 unsigned ptr;
 ++npxt;
 if (npxt > almxxt) {
  newline();
  printf("alloextra fails");
  newline();
  printf(" at %u", npxt);
  newline();
  printf(":");
  newline();
  printf("ctl-c to end");
  getch();
  fix();
  exit(1);
 }
 if (npxt > mxxt) {
  mxxt = npxt;
 }
 lastxt += 2;
 ++avxt;
 ptr = peek(fxt, lastxt);
 return (ptr);
}

void freeextra(ptr)
unsigned ptr;
{
 unsigned temp, index;
 --npxt;
 index = peek(ptr,0);
 temp = peek(fxt,lastxt);
 poke(temp,0,index);
 poke(fxt,index,temp);
 poke(fxt,lastxt,ptr);
 poke(ptr,0,lastxt);
 lastxt -= 2;
 --avxt;
}




struct link *locate(key, where) /* location of some key <= key */
unsigned key;
struct link *where;  /* a sorted list starts with key=zero */
{
 struct link *lastlink;
 if (where->loc == key) return (where);
 lastlink = where;
 if (where->loc < key) {
  do  {
   if (where->loc > key) return (lastlink);
   lastlink = where;
   where = where->nextl;
  }
  while (where);
 }
 else if (where->loc > key) {
  do {
   if (where->loc <= key)  return (where);
   where = where->prevl;
  }
  while (where);
 }
 return (lastlink);
}

unsigned member(key, where) /* not necessary for insert */
unsigned key;
struct link *where;  /* use locate prior to member */
{
 if (where->loc == key) return (1);
 return (0);
}

struct link *insert(key, where) /* head=insert(0,0); to init */
unsigned key;
struct link *where;  /* use locate prior to insert */
{
 struct link *head, *temp, *linkp;
 if (!where) {
  head = (struct link *) allosmall();
  head->nextl = 0;
  head->prevl = 0;
  head->loc = 0;
  return (head);
 }
 if (where->loc == key) return (where);
 temp = (struct link *) allosmall();
 temp->prevl = where;
 temp->nextl = where->nextl;
 if (where->nextl) where->nextl->prevl = temp;
 where->nextl = temp; /* this must be last pointer changed */
 temp->loc = key;
 return (temp);
}

struct link *delete(where)
struct link *where;
{
 struct link *prev, *next;
 struct link *last, *first;
 if (where->prevl) where->prevl->nextl = where->nextl;
 if (where->nextl) where->nextl->prevl = where->prevl;
 prev = where->prevl;
 freesmall(where);
 return (prev);
}

unsigned xtlocate(key, where) /* location of some key <= key */
unsigned key;
unsigned where;  /* a sorted list starts with key=zero */
{
 unsigned lastlink;
 if (peek(where,LOC) == key) return (where);
 lastlink = where;
 if (peek(where,LOC) < key) {
  do {
   if (peek(where,LOC) > key) return (lastlink);
   lastlink = where;
   where = peek(where,NEXTL);
  } while (where);
 }
 else if (peek(where,LOC) > key) {
  do {
   if (peek(where,LOC) <= key) return (where);
   where = peek(where,PREVL);
  } while (where);
 }
 return (lastlink);
}

unsigned xtmember(key, where) /* not necessary for insert */
unsigned key;
unsigned where;         /* use locate prior to member */
{
 if (peek(where,LOC) == key)
  return (1);
 else return (0);
}

unsigned xtinsert(key, where) /* head=xtinsert(0,0); to init */
unsigned key;
unsigned where;  /* use locate prior to insert */
{
 unsigned head,temp,linkp;
 if (!where)
 {
  head = alloextra();
  poke(head,NEXTL, 0);
  poke(head,PREVL, 0);
  poke(head,LOC, 0);
  return (head);
 }
 if (peek(where,LOC) == key) temp = where;
 else {
  temp = alloextra();
  poke(temp,PREVL, where);
  poke(temp,NEXTL, peek(where,NEXTL));
  if (peek(where,NEXTL)) poke(peek(where,NEXTL),PREVL, temp);
  poke(where,NEXTL, temp);
  poke(temp,LOC, key);
 }
 return (temp);
}

unsigned xtdelink(where)
unsigned where;
{
 unsigned prev, next;
 prev = where;
 if (peek(where,PREVL)) {
  poke(peek(where,PREVL),NEXTL, peek(where,NEXTL));
  if (peek(where,NEXTL)) poke(peek(where,NEXTL),PREVL, peek(where,PREVL));
  prev = peek(where,PREVL);
 }
 return (prev);
}

unsigned xtrelink(where)
unsigned where;
{
 unsigned prev, next;
 prev = where;
 if (peek(where,PREVL)) poke(peek(where,PREVL),NEXTL, where);
 if (peek(where,NEXTL)) poke(peek(where,NEXTL),PREVL, where);
 return (prev);
}

unsigned xtdelete(where)
unsigned where;
{
 unsigned prev;
 prev = xtdelink(where);
 freeextra(where);
 return (prev);
}

unsigned uzinsert(unsigned loc, unsigned ptr)
{ /* user's responsibility to check that loc is not xtmember of ptr list */
 unsigned tranp;
 ptr = xtinsert(loc, ptr);
 if (ptr) {
  tranp = movep->transact;
  ++ntrans;
  tranp = xtlocate(ntrans, tranp);
  tranp = xtinsert(ntrans, tranp);
  poke(tranp, LEVEL, 1); /* code to indicate transaction was xtinsert */
  poke(tranp, (LEVEL+2), ptr);
 }
 return(ptr);
}

unsigned uzdelink(unsigned ptr)
{
 unsigned tranp;
 if (ptr) {
  tranp = movep->transact;
  ++ntrans;
  tranp = xtlocate(ntrans, tranp);
  tranp = xtinsert(ntrans, tranp);
  poke(tranp, LEVEL, 2); /* code for xtdelink */
  poke(tranp, (LEVEL+2), ptr);
 }
 ptr = xtdelink(ptr);
 return(ptr);
}

void uzgvmod(unsigned *ptr, unsigned newval) /* modify global variable */
{ /* user's responsibility to check that value is actually bing changed */
 unsigned tranp;
 if (ptr) {
  tranp = movep->transact;
  ++ntrans;
  tranp = xtlocate(ntrans, tranp);
  tranp = xtinsert(ntrans, tranp);
  poke(tranp, LEVEL, 3); /* code for assignment of unsigned variable */
  poke(tranp, (LEVEL+2), ptr); /* store location of unsigned variable */
  poke(tranp, (LEVEL+4), *ptr); /* store old value */
  *ptr = newval;
 }
}

void uzxlmod(segptr, offset, value) /* modify xtlist link */
unsigned segptr, offset, value;
{ /* user's responsibility to check that value is actually bing changed */
 unsigned tranp;
 tranp = movep->transact;
 ++ntrans;
 tranp = xtlocate(ntrans, tranp);
 tranp = xtinsert(ntrans, tranp);
 poke(tranp, LEVEL, 4); /* code for assignment of unsigned variable */
 poke(tranp, (LEVEL+2), segptr); /* store location of unsigned variable */
 poke(tranp, (LEVEL+4), offset);
 poke(tranp, (LEVEL+6), peek(segptr, offset)); /* store old value */
 poke(segptr, offset, value);
}

int maxcompare(unsigned al, unsigned ah, unsigned bl, unsigned bh)
{
 if (ah < bh) return(1);
 if (ah > bh) return(-1);
 if (al > bl) return(1);
 if (al < bl) return(-1);
 return(0);
}

unsigned maxlocate(key, score, where) /* location of prev score:key */
unsigned key;    /* non-negative secondary sort value */
unsigned score;  /* non-negative primary sort value */
unsigned where;  /* segment pointer to a sorted list */
{
 unsigned lastlink;
 unsigned lcn, lvl, lc, lv;
 lcn = peek(where, LOC);
 lvl = peek(where, LEVEL);
 if (!maxcompare(lcn, lvl, key, score)) return (where);
 lastlink = where;
 if (maxcompare(lcn, lvl, key, score) < 0) {
  do {
   lcn = peek(where, LOC);
   lvl = peek(where, LEVEL);
   if (maxcompare(lcn, lvl, key, score) > 0) return (lastlink);
   lastlink = where;
   where = peek(where, NEXTS);
  } while (where);
 }
 else if (maxcompare(lcn, lvl, key, score) > 0) {
  do {
   lcn = peek(where, LOC);
   lvl = peek(where, LEVEL);
   if (maxcompare(lcn, lvl, key, score) <= 0) return (where);
   lastlink = where;
   where = peek(where, PREVS);
  } while (where);
 }
 return (lastlink);
}

void maxsort(unsigned indexes)
{
 unsigned index, score, indexp, jndexp;
 indexp = indexes;
 jndexp = indexes;
 poke(jndexp, LEVEL, POSINF); /* sorted so that max LEVEL first */
 poke(jndexp, PREVS, 0);
 poke(jndexp, NEXTS, 0);
 indexp = peek(indexp, NEXTL);
 if (indexp) {
  do {
   index = peek(indexp, LOC);
   score = peek(indexp, LEVEL);
   jndexp = maxlocate(index, score, jndexp);
   poke(indexp, NEXTS, peek(jndexp, NEXTS));
   poke(jndexp, NEXTS, indexp);
   poke(indexp, PREVS, jndexp);
   jndexp = peek(indexp, NEXTS);
   if (jndexp) poke(jndexp, PREVS, indexp);
   jndexp = indexp;
   indexp = peek(indexp, NEXTL);
  } while (indexp);
 }
}

int mincompare(unsigned al, unsigned ah, unsigned bl, unsigned bh)
{
 if (ah > bh) return(1);
 if (ah < bh) return(-1);
 if (al > bl) return(1);
 if (al < bl) return(-1);
 return(0);
}

unsigned minlocate(key, score, where) /* location of prev score:key */
unsigned key;    /* non-negative secondary sort value */
unsigned score;  /* non-negative primary sort value */
unsigned where;  /* segment pointer to a sorted list */
{
 unsigned lastlink;
 unsigned lcn, lvl, lc, lv;
 lcn = peek(where, LOC);
 lvl = peek(where, LEVEL);
 if (!mincompare(lcn, lvl, key, score)) return (where);
 lastlink = where;
 if (mincompare(lcn, lvl, key, score) < 0) {
  do {
   lcn = peek(where, LOC);
   lvl = peek(where, LEVEL);
   if (mincompare(lcn, lvl, key, score) > 0) return (lastlink);
   lastlink = where;
   where = peek(where, NEXTS);
  } while (where);
 }
 else if (mincompare(lcn, lvl, key, score) > 0) {
  do {
   lcn = peek(where, LOC);
   lvl = peek(where, LEVEL);
   if (mincompare(lcn, lvl, key, score) <= 0) return (where);
   where = peek(where, PREVS);
  } while (where);
 }
 return (lastlink);
}

void minsort(unsigned indexes)
{
 unsigned index, score, indexp, jndexp;
 indexp = indexes;
 jndexp = indexes;
 poke(jndexp, LEVEL, NEGINF); /* sorted so that min LEVEL first */
 poke(jndexp, PREVS, 0);
 poke(jndexp, NEXTS, 0);
 indexp = peek(indexp, NEXTL);
 if (indexp) {
  do {
   index = peek(indexp, LOC);
   score = peek(indexp, LEVEL);
   jndexp = minlocate(index, score, jndexp);
   poke(indexp, NEXTS, peek(jndexp, NEXTS));
   poke(jndexp, NEXTS, indexp);
   poke(indexp, PREVS, jndexp);
   jndexp = peek(indexp, NEXTS);
   if (jndexp) poke(jndexp, PREVS, indexp);
   jndexp = indexp;
   indexp = peek(indexp, NEXTL);
  } while (indexp);
 }
}

void xtfreelist(linkp)
unsigned linkp;
{
 unsigned nextlink;
 if (linkp) {
  do {
   nextlink = peek(linkp,NEXTL);
   freeextra(linkp);
   linkp = nextlink;
  } while (linkp);
 }
}

void xtfreetri(linkp)
unsigned linkp;
{
 unsigned nextlink;
 unsigned jndexes;
 if (linkp) {
  do {
   if (peek(linkp, PREVL)) {
    jndexes = peek(linkp, LEVEL);
    if (jndexes) xtfreelist(jndexes);
   }
   nextlink = peek(linkp,NEXTL);
   freeextra(linkp);
   linkp = nextlink;
  } while (linkp);
 }
}

void xtfreetree(linkp)
unsigned linkp;
{
 unsigned nextlink;
 unsigned jndexes;
 if (linkp) {
  do {
   if (peek(linkp, PREVS)) {
    jndexes = peek(linkp, (LEVEL+2));
    if (jndexes) xtfreetree(jndexes);
   }
   nextlink = peek(linkp, NEXTS);
   freeextra(linkp);
   linkp = nextlink;
  } while (linkp);
 }
}

void freelist(linkp)
struct link *linkp;
{
 struct link *nextlink;
 if (linkp) {
  do {
   nextlink = linkp->nextl;
   freesmall(linkp);
   linkp = nextlink;
  }
  while (linkp);
 }
}

unsigned merge(head, tail)
struct link *head, *tail;
{
 unsigned key;
 unsigned more;
 more = 0;
 tail = tail->nextl;
 if (tail) {
  do {
   key = tail->loc;
   head = locate(key, head);
   if (!member(key, head)) {
    head = insert(key, head);
    ++more;
   }
   tail = tail->nextl;
  } while (tail);
 }
 return (more);
}

unsigned mixmerge(head, tail)
unsigned head;
struct link *tail;
{
 unsigned key;
 unsigned more;
 more = 0;
 tail = tail->nextl;
 if (tail) {
  do {
   key = tail->loc;
   head = xtlocate(key, head);
   if (!xtmember(key, head)) {
    head = xtinsert(key, head);
    ++more;
   }
   tail = tail->nextl;
  } while (tail);
 }
 return (more);
}

void xmerge(head, tail, exception)
struct link *head, *tail, *exception;
{
 unsigned key;
 struct link *hp, *tp, *ep;
 hp = head;
 tp = tail;
 ep = exception;
 tp = tp->nextl;
 if (tp) {
  do {
   key = tp->loc;
   hp = locate(key, hp);
   ep = locate(key, ep);
   if (member(key, ep)) {
    if (member(key, hp)) hp = delete(hp);
   }
   else hp = insert(key, hp);
   tp = tp->nextl;
  }
  while (tp);
 }
}

struct link *headlist(linkp)
struct link *linkp;
{
 struct link *head;
 do {
  head = linkp;
  linkp = linkp->prevl;
 }
 while (linkp);
 return (head);
}

struct link *taillist(linkp)
struct link *linkp;
{
 struct link *tail;
 do {
  tail = linkp;
  linkp = linkp->nextl;
 }
 while (linkp);
 return (tail);
}

unsigned xttaillist(xtlinkp)
unsigned xtlinkp;
{
 unsigned tail;
 do {
  tail = xtlinkp;
  xtlinkp = peek(xtlinkp, NEXTL);
 }
 while (xtlinkp);
 return (tail);
}

void uzfreelist(linkp)
unsigned linkp;
{
 if (linkp) {
  linkp = xttaillist(linkp);
  do {
   linkp = uzdelink(linkp);
  } while (peek(linkp, PREVL));
 }
}

/*
unsigned *delink(head, linkp)
struct link *head, *linkp;
{
 struct link *prev, *next;
 struct link *last, *first;
 first = head;
 last = head->taill;
 prev = linkp->nextl;
 if (prev) prev->prevl = linkp->prevl;
 next = linkp->prevl;
 if (next) next->nextl = linkp->nextl;
 if (first == last) first = 0;
 else {
  if (first == linkp) {
   first->nextl->taill = first->taill;
   first->nextl->prevl = 0;
   first = first->nextl;
  }
  if (last == linkp) {
   last->prevl->nextl = 0;
   first->taill = last->prevl;
  }
 }
 return (first);
}
*/


/*
unsigned mergelist(head, tail)
struct link *head, *tail;
{
 struct link *first;
 first = head;
 if (tail) {
  if (head) {
   tail->prevl = head->taill;
   head->taill->nextl = tail;
   head->taill = tail->taill;
  }
  else first = tail;
 }
 return (first);
}
*/


void realxy(index, px, py)    /* usage: realxy(index, &x, &y) */
unsigned index, *px, *py;
{
 #if DDD
 unsigned z;
 z = ((index-1) / nsize) / nsize + 1;
 index -= (z-1) * nsize * nsize;
 #endif
 *px = (index - 1) / nsize;
 *py = index - *px * nsize;
 ++*px;
}

void xy(index, px, py)    /* usage: xy(index, &x, &y) */
unsigned index, *px, *py;
{
 #if DDD
 unsigned z;
 z = ((index-1) / nsize) / nsize + 1;
 index -= (z-1) * nsize * nsize;
 #endif
 *px = X[index];
 *py = Y[index];
}

unsigned fxy(x, y)
unsigned x, y;
{
 unsigned index;
 index = (x-1) * nsize + y;
 return(index);
}

unsigned fxyz(x, y, z)
unsigned x, y, z;
{
 unsigned index;
 index = (x-1) * nsize + y;
 index += (z-1) * nsize * nsize;
 return(index);
}

unsigned sameplane(unsigned index, unsigned jndex)
{
 unsigned same;
 unsigned zi, zj;
 same = 0;
 zi = ((index-1) / nsize) / nsize;
 zj = ((jndex-1) / nsize) / nsize;
 if (zi == zj) same = 1;
 return(same);
}

unsigned shift(index, right, down)
unsigned index;
int right, down;
{
 unsigned jndex, z, x, y;
 jndex = 0;
 #if DDD
 y = ((index-1) / nsize) / nsize + 1;
 index -= (y-1) * nsize * nsize;
 #endif
 xy(index, &z, &x);
 right += x;
 #if DONUT
 if (right < 1) right += nsize;
 if (right > nsize) right -= nsize;
 #endif
 if ((right > 0) && (right <= nsize)) {
  down += z;
  #if DONUT
  if (down < 1) down += nsize;
  if (down > nsize) down -= nsize;
  #endif
  if ((down > 0) && (down <= nsize)) {
   x = right;
   z = down;
   jndex = fxy(z, x);
   #if DDD
   jndex += (y-1) * nsize * nsize;
   #endif
  }
 }
 return(jndex);
}

unsigned north(index)
unsigned index;
{
 unsigned jndex;
 jndex = 0;
 if (index) {
  if (!dizzy) jndex = shift(index, 0, -1);
  else if (dizzy == 1) jndex = shift(index, -1, 0);
  else if (dizzy == 2) jndex = shift(index, 0, 1);
  else if (dizzy == 3) jndex = shift(index, 1, 0);
 }
 return(jndex);
}

unsigned west(index)
unsigned index;
{
 unsigned jndex;
 jndex = 0;
 if (index) {
  if (!dizzy) jndex = shift(index, -1, 0);
  else if (dizzy == 1) jndex = shift(index, 0, 1);
  else if (dizzy == 2) jndex = shift(index, 1, 0);
  else if (dizzy == 3) jndex = shift(index, 0, -1);
 }
 return(jndex);
}

unsigned east(index)
unsigned index;
{
 unsigned jndex;
 jndex = 0;
 if (index) {
  if (!dizzy) jndex = shift(index, 1, 0);
  else if (dizzy == 1) jndex = shift(index, 0, -1);
  else if (dizzy == 2) jndex = shift(index, -1, 0);
  else if (dizzy == 3) jndex = shift(index, 0, 1);
 }
 return(jndex);
}

unsigned south(index)
unsigned index;
{
 unsigned jndex;
 jndex = 0;
 if (index) {
  if (!dizzy) jndex = shift(index, 0, 1);
  else if (dizzy == 1) jndex = shift(index, 1, 0);
  else if (dizzy == 2) jndex = shift(index, 0, -1);
  else if (dizzy == 3) jndex = shift(index, -1, 0);
 }
 return(jndex);
}

unsigned up(index)
unsigned index;
{
 unsigned jndex, z;
 jndex = 0;
 if (index) {
  z = ((index-1) / nsize) / nsize + 1;
  if (z < nsize) jndex = index + nsize * nsize;
 }
 return(jndex);
}

unsigned down(index)
unsigned index;
{
 unsigned jndex, z;
 jndex = 0;
 if (index) {
  z = ((index-1) / nsize) / nsize + 1;
  if (z > 1) jndex = index - nsize * nsize;
 }
 return(jndex);
}

unsigned howfar(index, jndex)
unsigned index, jndex;
{
 unsigned dist;
 int xa, ya, xb, yb;
 unsigned alpha, beta;
 xy(index, &xa, &ya);
 xy(jndex, &xb, &yb);
 alpha = abs(xa-xb);
 beta = abs(ya-yb);
 if (alpha > beta) dist = alpha + alpha + beta;
 else dist = alpha + beta + beta;
 return(dist);
}

unsigned manhat(index, jndex)
unsigned index, jndex;
{
 unsigned dist;
 unsigned xa, ya, xb, yb;
 unsigned alpha, beta;
 xy(index, &xa, &ya);
 xy(jndex, &xb, &yb);
 alpha = abs(xa-xb);
 beta = abs(ya-yb);
 dist = alpha + beta;
 return(dist);
}

unsigned cartesian(index, jndex)
unsigned index, jndex;
{
 unsigned dist;
 unsigned xa, ya, xb, yb;
 unsigned alpha, beta;
 xy(index, &xa, &ya);
 xy