#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