Moved to vt100-games repository
This commit is contained in:
parent
69862652b5
commit
a716951dab
62
Compiling.md
62
Compiling.md
@ -1,62 +0,0 @@
|
|||||||
# Compiling Gammon IV
|
|
||||||
|
|
||||||
## Requirements
|
|
||||||
|
|
||||||
To compile this program, you need the following:
|
|
||||||
|
|
||||||
* The Software Toolworks' C/80 v3.1 compiler for CP/M
|
|
||||||
* Microsoft MACRO-80 assembler (M80.com)
|
|
||||||
* Microsoft LINK-80 linker (L80.COM)
|
|
||||||
|
|
||||||
All of these tools can be found here:
|
|
||||||
http://www.retroarchive.org/cpm/lang/lang.htm
|
|
||||||
|
|
||||||
## Configuration
|
|
||||||
|
|
||||||
The C compiler needs to be configured in order to be able to compile Gammon IV.
|
|
||||||
|
|
||||||
Just use CCONFIG.COM to make the following settings:
|
|
||||||
|
|
||||||
Symbol table size: 512
|
|
||||||
String constant table: 3200
|
|
||||||
Dump constants after each routine: YES
|
|
||||||
Macro table size: 500
|
|
||||||
Switch table size: 128
|
|
||||||
Structure table size: 200
|
|
||||||
Merge duplicate string constants: YES
|
|
||||||
Assembler: C/80's AS
|
|
||||||
Initialize arrays to zero: < 256 BYES ONLY
|
|
||||||
Generate ROMable code in Macro-80: YES
|
|
||||||
Screen size: 24 (doesn't matter)
|
|
||||||
Generate slightly larger, faster code: NO
|
|
||||||
Sign extension on char to int conversion: YES
|
|
||||||
Device for library files: A: (your choice)
|
|
||||||
|
|
||||||
## Compilation
|
|
||||||
|
|
||||||
I assume that all of the following files are placed on a hard disk or "big" floppy disk.
|
|
||||||
If you are compiling this game on a old system with limited disk space, please look into backgmmn.c, where you can find tips on how to distribute the files onto several disks.
|
|
||||||
|
|
||||||
The following files are needed:
|
|
||||||
BACKGMMN.C, GAMEPLAN.C, GAMEPLAN.HDR, MYLIB2.C,
|
|
||||||
|
|
||||||
From the C compiler:
|
|
||||||
PRINTF.C, STDLIB.REL, CLIBRARY.REL, C.COM
|
|
||||||
|
|
||||||
Assembler/Linker:
|
|
||||||
L80.COM, M80.COM
|
|
||||||
|
|
||||||
To use the submit scripts, you also need ``SUBMIT.COM`` from your CP/M installation.
|
|
||||||
|
|
||||||
Using ``SUBMIT BGMAKE``, all steps of compiling, assembling and linking will run.
|
|
||||||
|
|
||||||
Using ``SUBMIT BGCLEAN``, all compiled files and intermediary files will be deleted.
|
|
||||||
|
|
||||||
If you don't want to use the script or just want to compile some parts, these steps are taken in the script:
|
|
||||||
|
|
||||||
c -m backgmmn
|
|
||||||
m80 =backgmmn
|
|
||||||
c -m gameplan
|
|
||||||
m80 =gameplan
|
|
||||||
l80 backgmmn,gameplan,stdlib/s,clibrary/s,backgmmn/n/e
|
|
||||||
|
|
2278
Original/backgmmn.c
2278
Original/backgmmn.c
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Binary file not shown.
@ -1,14 +0,0 @@
|
|||||||
era *.bak
|
|
||||||
era *.mac
|
|
||||||
era backgmmn.rel
|
|
||||||
era gameplan.rel
|
|
||||||
era backgmmn.com
|
|
||||||
b:c -m backgmmn
|
|
||||||
b:m80 =backgmmn
|
|
||||||
era backgmmn.mac
|
|
||||||
b:c -m gameplan
|
|
||||||
b:m80 =gameplan
|
|
||||||
era gameplan.mac
|
|
||||||
b:l80 backgmmn,gameplan,stdlib/s,clibrary/s,backgmmn/n/e
|
|
||||||
backgmmn
|
|
||||||
|
|
@ -1,866 +0,0 @@
|
|||||||
|
|
||||||
/* Gammon IV, by David C. Oshel, Ames, Iowa */
|
|
||||||
|
|
||||||
/*--------------------------------------------------------------------*/
|
|
||||||
/* GAMEPLAN.C -- separately compiled module, contains the tactics and */
|
|
||||||
/* strategy for making the computer's move in Gammon IV */
|
|
||||||
/* BACKGMMN.REL calls MyMove(), MyMove() calls topstone */
|
|
||||||
/* and movestone and a few others. Uses the globals in */
|
|
||||||
/* GAMEPLAN.HDR quite heavily. Bgversion declared here */
|
|
||||||
/*--------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#include "gameplan.hdr" /* contains external, global declarations */
|
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------*/
|
|
||||||
/* */
|
|
||||||
/* Bgversion is an external reference in the main module. Use this string */
|
|
||||||
/* to take credit for a decent gameplaying algorithm if you find one! */
|
|
||||||
/* */
|
|
||||||
char *bgversion = ".20 -April 1, 1986- by David C. Oshel";
|
|
||||||
/*....v....1....v....2....v....3....v...*/
|
|
||||||
/* just 38 characters for version info! */
|
|
||||||
/* */
|
|
||||||
/*-------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
|
|
||||||
/*=============================================*/
|
|
||||||
/* M Y M O V E */
|
|
||||||
/*=============================================*/
|
|
||||||
|
|
||||||
|
|
||||||
naked() { /* am I leaving too many blots? */
|
|
||||||
static int i, clink;
|
|
||||||
i = 24; clink = 0;
|
|
||||||
while (i) {
|
|
||||||
if (point[i].stones == 1 && point[i].owner == ME) clink++;
|
|
||||||
i--;
|
|
||||||
}
|
|
||||||
return (clink > 2);
|
|
||||||
} /* end: naked */
|
|
||||||
|
|
||||||
|
|
||||||
yourfolly() { /* look for lotsa blots in your inner table */
|
|
||||||
static int i, clink;
|
|
||||||
i = 18; clink = 0;
|
|
||||||
while (i < 25) {
|
|
||||||
if (point[i].owner == YU && point[i].stones == 1)
|
|
||||||
clink++;
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
return (clink >= 3);
|
|
||||||
} /* end: yourfolly */
|
|
||||||
|
|
||||||
|
|
||||||
goodboard() { /* look for four made points near my inner table */
|
|
||||||
static int i, clank, clink;
|
|
||||||
i = 9; clank = 0;
|
|
||||||
while (i > 3) {
|
|
||||||
if (point[i].owner == ME && point[i].stones > 1) clank++;
|
|
||||||
i--;
|
|
||||||
}
|
|
||||||
if (clank > 4) return (TRUE); /* bar is nearly blocked */
|
|
||||||
|
|
||||||
i = 6; clank = clink = 0;
|
|
||||||
while (i) {
|
|
||||||
if (point[i].owner != ME)
|
|
||||||
;
|
|
||||||
else if (point[i].stones == 1) clink++; else clank++;
|
|
||||||
i--;
|
|
||||||
}
|
|
||||||
return (clank > 3 && clink < 2);
|
|
||||||
} /* end: goodboard */
|
|
||||||
|
|
||||||
|
|
||||||
bearoff() {
|
|
||||||
return (topstone(ME) < 7);
|
|
||||||
} /* end: bearoff */
|
|
||||||
|
|
||||||
|
|
||||||
scanahead( from ) int from; {
|
|
||||||
static int count;
|
|
||||||
|
|
||||||
count = 0;
|
|
||||||
while (--from > 0) {
|
|
||||||
++count;
|
|
||||||
if ( point[ from ].owner == YU ) return (count);
|
|
||||||
}
|
|
||||||
return (7);
|
|
||||||
|
|
||||||
} /* end: scanahead */
|
|
||||||
|
|
||||||
|
|
||||||
endgame() { /* Is no strategy required from here on in? */
|
|
||||||
return ( (25 - topstone(YU)) > topstone(ME) );
|
|
||||||
} /* end: endgame */
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------*/
|
|
||||||
/* MATCHUP */
|
|
||||||
/* */
|
|
||||||
/* 2-stone functions that force the choice of the next move. */
|
|
||||||
/* These are the HEART and SOUL of this backgammon algorithm! */
|
|
||||||
/*------------------------------------------------------------*/
|
|
||||||
|
|
||||||
setpend( from, to ) int from, to; {
|
|
||||||
pending.fr = from;
|
|
||||||
pending.to = to;
|
|
||||||
pending.flag = TRUE;
|
|
||||||
} /* end: setpend */
|
|
||||||
|
|
||||||
|
|
||||||
clrpend() {
|
|
||||||
pending.flag = FALSE;
|
|
||||||
} /* end: clrpend */
|
|
||||||
|
|
||||||
|
|
||||||
natural(f1,t1,f2,t2) int f1,t1,f2,t2; {
|
|
||||||
clrpend();
|
|
||||||
if (point[t2].stones == 1 && t1 == f2) setpend(f2,t2);
|
|
||||||
return (pending.flag);
|
|
||||||
} /* end: natural */
|
|
||||||
|
|
||||||
|
|
||||||
matchup( test4 ) int (* test4)(); {
|
|
||||||
static int i, j, ti, tj;
|
|
||||||
|
|
||||||
if ( pending.flag ) return (FALSE); /* this is probably redundant */
|
|
||||||
|
|
||||||
for (i = 1; i < 26; i++) {
|
|
||||||
ti = list[0][i];
|
|
||||||
if ( ti == ERROR ) goto zoo;
|
|
||||||
for (j = 1; j < 26; j++) {
|
|
||||||
tj = list[1][j];
|
|
||||||
if ( tj == ERROR ) goto voo;
|
|
||||||
if ( (* test4)( i, ti, j, tj ) ) {
|
|
||||||
lurch( i, ti, 0);
|
|
||||||
return (TRUE);
|
|
||||||
}
|
|
||||||
voo: ;
|
|
||||||
}
|
|
||||||
zoo: ;
|
|
||||||
}
|
|
||||||
return (FALSE);
|
|
||||||
|
|
||||||
} /* end: matchup */
|
|
||||||
|
|
||||||
|
|
||||||
matchhi( test4 ) int (* test4)(); {
|
|
||||||
static int i, j, ti, tj;
|
|
||||||
|
|
||||||
if ( pending.flag ) return (FALSE); /* this is probably redundant */
|
|
||||||
|
|
||||||
for (i = 1; i < 26; i++) {
|
|
||||||
ti = list[1][i];
|
|
||||||
if ( ti == ERROR ) goto zoo;
|
|
||||||
for (j = 1; j < 26; j++) {
|
|
||||||
tj = list[0][j];
|
|
||||||
if ( tj == ERROR ) goto voo;
|
|
||||||
if ( (* test4)( i, ti, j, tj ) ) {
|
|
||||||
lurch( i, ti, 1);
|
|
||||||
return (TRUE);
|
|
||||||
}
|
|
||||||
voo: ;
|
|
||||||
}
|
|
||||||
zoo: ;
|
|
||||||
}
|
|
||||||
return (FALSE);
|
|
||||||
|
|
||||||
} /* end: matchhi */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*--------------------------------------------------------*/
|
|
||||||
/* CLOCKWISE and COUNTERCLOCK */
|
|
||||||
/* */
|
|
||||||
/* the rest of these are single-stone decisions based on */
|
|
||||||
/* rules of thumb, board-scanning functions */
|
|
||||||
/*--------------------------------------------------------*/
|
|
||||||
|
|
||||||
plainstupid( from ) int from; { /* don't break a safe point */
|
|
||||||
return (from < 13 && (point[from].stones == 2 && scanahead(from) < 7));
|
|
||||||
} /* end: plainstupid */
|
|
||||||
|
|
||||||
|
|
||||||
unwise( innertablept ) int innertablept; {
|
|
||||||
/* if it's a hit, just for god's sake don't put him on the bar!! */
|
|
||||||
if ( innertablept < 7 ) {
|
|
||||||
if (point[ innertablept ].owner == YU ||
|
|
||||||
point[ YRBAR ].stones > 0)
|
|
||||||
return (TRUE);
|
|
||||||
}
|
|
||||||
return(FALSE);
|
|
||||||
} /* end: unwise */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
covermine( from, to ) int from, to; {
|
|
||||||
if ( from < 8 ) return(FALSE);
|
|
||||||
return ( (point[ to ].stones == 1) && (point[ to ].owner == ME) );
|
|
||||||
} /* end: covermine */
|
|
||||||
|
|
||||||
|
|
||||||
idareyou( from, to ) int from, to; {
|
|
||||||
if (unwise( to )) return (FALSE);
|
|
||||||
if ( (point[ from ].stones != 2)
|
|
||||||
&& (point[ to ].stones < 2)
|
|
||||||
&& (scanahead( to ) > 6) ) return ( TRUE );
|
|
||||||
else return (FALSE);
|
|
||||||
} /* end: idareyou */
|
|
||||||
|
|
||||||
|
|
||||||
hitandrun( from, to ) int from, to; {
|
|
||||||
return ( point[ to ].owner == YU );
|
|
||||||
} /* end: hitandrun */
|
|
||||||
|
|
||||||
|
|
||||||
dbuild( from, to ) int from, to; {
|
|
||||||
static int diceleft;
|
|
||||||
diceleft = (myturns? 2 + movesleft: movesleft);
|
|
||||||
if (diceleft > 1) {
|
|
||||||
/* can't possibly be only one stone on from point */
|
|
||||||
/* or kamikaze would have covered it on last move */
|
|
||||||
return ( point[to].stones == 0 );
|
|
||||||
}
|
|
||||||
return (FALSE);
|
|
||||||
} /* end: dbuild */
|
|
||||||
|
|
||||||
|
|
||||||
kamikaze( from, to ) int from, to; {
|
|
||||||
/* cover my distant blot, or razzle-dazzle 'em with the long doubles hit */
|
|
||||||
static int j, k, diceleft;
|
|
||||||
|
|
||||||
k = from;
|
|
||||||
j = from - to;
|
|
||||||
diceleft = myturns * movesleft; /* NB: 2*2 == 2+2, "fourtunately" */
|
|
||||||
while ( diceleft-- ) { /* predicting where doubles land is easy! */
|
|
||||||
k -= j;
|
|
||||||
if (k < 1) return (FALSE); /* out of bounds */
|
|
||||||
if ( point[ k ].stones == 0 ) continue; /* simplify */
|
|
||||||
if ( point[ k ].stones == 1 ) /* found my blot or yours? */
|
|
||||||
return (TRUE);
|
|
||||||
else if ( point[k].owner == YU ) /* found your blockade? */
|
|
||||||
return (FALSE);
|
|
||||||
else continue; /* found my safe point, so ignore it */
|
|
||||||
}
|
|
||||||
return (FALSE);
|
|
||||||
|
|
||||||
} /* end: kamikaze */
|
|
||||||
|
|
||||||
|
|
||||||
hittite( from, to ) int from, to; {
|
|
||||||
return (hitandrun(from,to) && to > 9);
|
|
||||||
} /* end: hittite */
|
|
||||||
|
|
||||||
|
|
||||||
safehit( from, to ) int from, to; {
|
|
||||||
return (hittite(from,to) && idareyou(from,to));
|
|
||||||
} /* end: safehit */
|
|
||||||
|
|
||||||
|
|
||||||
foolsdemise( from, to ) int from, to; {
|
|
||||||
/* annihilate orphaned blots in enemy's inner, my outer table */
|
|
||||||
return (to > 17 && point[to].owner == YU);
|
|
||||||
} /* end: foolsdemise */
|
|
||||||
|
|
||||||
|
|
||||||
landonme( from, to ) int from, to; {
|
|
||||||
if ( plainstupid(from) ) return (FALSE);
|
|
||||||
if ( loneranger(from,to) ) {
|
|
||||||
if (from < 19 && to > 6) return(TRUE);
|
|
||||||
}
|
|
||||||
else return ( point[ to ].owner == ME && point[to].stones < 4);
|
|
||||||
} /* end: landonme */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* these evaluations have meaning only in the endgame */
|
|
||||||
|
|
||||||
|
|
||||||
nobackgammon( from, to ) int from, to; { /* endgame */
|
|
||||||
return (from > 19);
|
|
||||||
} /* end: nobackgammon */
|
|
||||||
|
|
||||||
|
|
||||||
crosstable( from, to ) int from, to; {
|
|
||||||
/* always move a table ahead if possible, in the endgame */
|
|
||||||
if (from < 7) return (FALSE);
|
|
||||||
if (from > 18 && to <= 18) return (TRUE);
|
|
||||||
if (from > 12 && to <= 12) return (TRUE);
|
|
||||||
if (from > 6 && to <= 6) return (TRUE);
|
|
||||||
return (FALSE);
|
|
||||||
} /* end: crosstable */
|
|
||||||
|
|
||||||
|
|
||||||
fiftytworule( from, to ) int from, to; { /* endgame */
|
|
||||||
static int p;
|
|
||||||
if (from < 7) return (FALSE); /* not in inner table! */
|
|
||||||
p = from % 6;
|
|
||||||
if (p == 0) return (TRUE); /* improve the six */
|
|
||||||
if (p != 5) return ( (to % 6) < 3 ); /* best improve under five */
|
|
||||||
} /* end: fiftytworule */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* these evaluations are universally applicable, last resort moves */
|
|
||||||
|
|
||||||
|
|
||||||
gohome( from, to ) int from, to; { /* always go home if you can */
|
|
||||||
return (to == MYHOME);
|
|
||||||
} /* end: gohome */
|
|
||||||
|
|
||||||
|
|
||||||
scatter( from, to ) int from, to; { /* scatter, esp. in the endgame */
|
|
||||||
if (plainstupid(from) || unwise(to)) return (FALSE);
|
|
||||||
return ( point[ from ].stones > 1 && point[ to ].stones == 0 );
|
|
||||||
} /* end: scatter */
|
|
||||||
|
|
||||||
|
|
||||||
runnerup( from, to ) int from, to; {
|
|
||||||
if (from < 10 || from > 18) return (FALSE);
|
|
||||||
return (TRUE);
|
|
||||||
} /* end: runnerup */
|
|
||||||
|
|
||||||
|
|
||||||
loneranger( from, to ) int from, to; {
|
|
||||||
return( point[ from ].stones == 1 );
|
|
||||||
} /* end: loneranger */
|
|
||||||
|
|
||||||
|
|
||||||
run( dummy1, dummy2 ) int dummy1, dummy2; { /* MUST move something! */
|
|
||||||
return (TRUE);
|
|
||||||
} /* end: run */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* clockwise and counterclock make a 1-stone choice on rules of thumb */
|
|
||||||
|
|
||||||
|
|
||||||
counterclock( test ) int (* test)(); {
|
|
||||||
static int i,j;
|
|
||||||
|
|
||||||
for (i = 0; i < 2; i++) {
|
|
||||||
for (j = 1; j < 25; j++) {
|
|
||||||
if ( list[i][j] == ERROR ) continue;
|
|
||||||
if ( (* test)( j, list[i][j] ) ) {
|
|
||||||
lurch( j, list[i][j], i);
|
|
||||||
return ( TRUE );
|
|
||||||
} } }
|
|
||||||
return (FALSE);
|
|
||||||
|
|
||||||
} /* end: counterclock */
|
|
||||||
|
|
||||||
|
|
||||||
clockwise( test ) int (* test)(); {
|
|
||||||
static int i,j;
|
|
||||||
|
|
||||||
for (i = 0; i < 2; i++) {
|
|
||||||
for (j = 25; j > 0; j--) {
|
|
||||||
if ( list[i][j] == ERROR ) continue;
|
|
||||||
if ( (* test)( j, list[i][j] ) ) {
|
|
||||||
lurch( j, list[i][j], i);
|
|
||||||
return ( TRUE );
|
|
||||||
} } }
|
|
||||||
return (FALSE);
|
|
||||||
|
|
||||||
} /* end: clockwise */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*-------------------------------------------*/
|
|
||||||
/* Make Prime */
|
|
||||||
/*-------------------------------------------*/
|
|
||||||
|
|
||||||
static int prmchk;
|
|
||||||
|
|
||||||
|
|
||||||
buildprime( f1,t1,f2,t2 ) int f1,t1,f2,t2; {
|
|
||||||
clrpend();
|
|
||||||
/* check for the doubles bug */
|
|
||||||
if ((dice[0] == dice[1]) && (point[f1].stones < 2)) return(FALSE);
|
|
||||||
|
|
||||||
/* look for the combination */
|
|
||||||
if ( t1 == prmchk && t2 == prmchk) setpend(f2,t2);
|
|
||||||
|
|
||||||
/* stick like glue to a made point, but doubles may move forward */
|
|
||||||
if (dice[0] != dice[1]) {
|
|
||||||
if ((f2 < 8) && (point[f2].stones == 2)) clrpend();
|
|
||||||
if ((f1 < 8) && (point[f1].stones == 2)) clrpend();
|
|
||||||
}
|
|
||||||
|
|
||||||
return(pending.flag);
|
|
||||||
|
|
||||||
} /* end: buildprime */
|
|
||||||
|
|
||||||
|
|
||||||
makeprime() {
|
|
||||||
static int i, tab[] = { ERROR,1,2,3,20,22,24,9,4,6,8,5,7 };
|
|
||||||
i = 12;
|
|
||||||
while (i) {
|
|
||||||
prmchk = tab[i];
|
|
||||||
i--;
|
|
||||||
if ( point[ prmchk ].stones > 1 ) continue;
|
|
||||||
else if ( matchup( buildprime ) ) return(TRUE);
|
|
||||||
}
|
|
||||||
return(FALSE);
|
|
||||||
} /* end: makeprime */
|
|
||||||
|
|
||||||
|
|
||||||
coverprime( from, to ) int from, to; {
|
|
||||||
return (((to == prmchk) &&
|
|
||||||
(point[prmchk].owner == ME)) &&
|
|
||||||
(point[from].stones != 2));
|
|
||||||
} /* coverprime */
|
|
||||||
|
|
||||||
|
|
||||||
cleanup() {
|
|
||||||
static int i, tab[] = { ERROR,1,2,3,20,22,24,9,4,6,8,5,7 };
|
|
||||||
i = 12;
|
|
||||||
while (i) {
|
|
||||||
prmchk = tab[i];
|
|
||||||
i--;
|
|
||||||
if ( point[ prmchk ].stones != 1 ) continue;
|
|
||||||
else if ( counterclock( coverprime ) ) return(TRUE);
|
|
||||||
}
|
|
||||||
return(FALSE);
|
|
||||||
} /* end: cleanup */
|
|
||||||
|
|
||||||
|
|
||||||
/*-------------------------------------*/
|
|
||||||
/* Walking Prime */
|
|
||||||
/*-------------------------------------*/
|
|
||||||
|
|
||||||
swivelhips( from, to ) int from, to; {
|
|
||||||
return ( from > prmchk );
|
|
||||||
} /* end: swivelhips */
|
|
||||||
|
|
||||||
|
|
||||||
slink( from, to ) int from, to; {
|
|
||||||
return( (from > prmchk) && (point[to].stones == 1) );
|
|
||||||
} /* end: slink */
|
|
||||||
|
|
||||||
|
|
||||||
weasel() {
|
|
||||||
if ( clockwise( slink ) )
|
|
||||||
return(TRUE);
|
|
||||||
if ( counterclock( swivelhips ) )
|
|
||||||
return(TRUE);
|
|
||||||
if ( clockwise( run ) )
|
|
||||||
return(TRUE);
|
|
||||||
} /* end: weasel */
|
|
||||||
|
|
||||||
ihaveprime( from ) int from; {
|
|
||||||
static int i, to, ez;
|
|
||||||
ez = 0;
|
|
||||||
for (i = 0; i < 6; i++) {
|
|
||||||
to = from - i;
|
|
||||||
if ((point[to].owner == ME) && (point[to].stones > 1)) ez++;
|
|
||||||
}
|
|
||||||
return (ez > 4);
|
|
||||||
} /* end: ihaveprime */
|
|
||||||
|
|
||||||
|
|
||||||
walkingprime() {
|
|
||||||
/* looks for the walking prime anywhere in the front tables */
|
|
||||||
/* then tries to bring up a runner from behind the prime, */
|
|
||||||
/* ensuring that a back stone WILL move before a front one */
|
|
||||||
static int i;
|
|
||||||
i = 12;
|
|
||||||
while (i > 5) {
|
|
||||||
if ( ihaveprime(i) ) {
|
|
||||||
prmchk = i;
|
|
||||||
if ( weasel() ) return (TRUE);
|
|
||||||
}
|
|
||||||
i--;
|
|
||||||
}
|
|
||||||
return(FALSE);
|
|
||||||
} /* end: walkingprime */
|
|
||||||
|
|
||||||
|
|
||||||
/*---------- Book Moves ----------*/
|
|
||||||
/* only valid if my move is first */
|
|
||||||
/*--------------------------------*/
|
|
||||||
|
|
||||||
zip(a,b,c,d) int a,b,c,d; {
|
|
||||||
lurch(a,b,0);
|
|
||||||
lurch(c,d,0);
|
|
||||||
movesleft = 0; return( TRUE );
|
|
||||||
} /* end: zip */
|
|
||||||
|
|
||||||
|
|
||||||
zoom( a,b,c,d,e,f,g,h ) int a,b,c,d,e,f,g,h; {
|
|
||||||
myturns = 0; zip(a,b,c,d); zip(e,f,g,h); return( TRUE );
|
|
||||||
} /* end: zoom */
|
|
||||||
|
|
||||||
|
|
||||||
book() {
|
|
||||||
int a,b;
|
|
||||||
if (!firstmove) return (FALSE);
|
|
||||||
firstmove = FALSE;
|
|
||||||
a = min(dice[0],dice[1]);
|
|
||||||
b = max(dice[0],dice[1]);
|
|
||||||
switch (level) {
|
|
||||||
case 0: { return ( book0(a,b) ); break; }
|
|
||||||
case 1: { return ( book1(a,b) ); break; }
|
|
||||||
case 2: { return ( book2(a,b) ); break; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
book0( a,b ) int a, b; {
|
|
||||||
switch (a) {
|
|
||||||
case 1: { switch (b) {
|
|
||||||
case 1: return ( zoom(8,7,8,7,6,5,6,5) );
|
|
||||||
case 2: return ( zip(24,23,13,11) );
|
|
||||||
case 3: return ( zip(8,5,6,5) );
|
|
||||||
case 4: return ( zip(24,23,13,9) );
|
|
||||||
case 5: return ( zip(24,23,13,8) );
|
|
||||||
case 6: return ( zip(13,7,8,7) );
|
|
||||||
}
|
|
||||||
break; }
|
|
||||||
case 2: { switch (b) {
|
|
||||||
case 2: return ( zoom(6,4,6,4,13,11,13,11) );
|
|
||||||
case 3: return ( zip(13,11,13,10) );
|
|
||||||
case 4: return ( zip(8,4,6,4) );
|
|
||||||
case 5: return ( zip(13,8,13,11) );
|
|
||||||
case 6: return ( zip(24,18,13,11) );
|
|
||||||
}
|
|
||||||
break; }
|
|
||||||
case 3: { switch (b) {
|
|
||||||
case 3: return ( zoom(13,10,13,10,10,7,10,7) );
|
|
||||||
case 4: return ( zip(13,10,13,9) );
|
|
||||||
case 5: return ( zip(13,10,13,8) );
|
|
||||||
case 6: return ( zip(24,18,13,10) );
|
|
||||||
}
|
|
||||||
break; }
|
|
||||||
case 4: { switch (b) {
|
|
||||||
case 4: return ( zoom(13,9,13,9,24,20,24,20) );
|
|
||||||
case 5: return ( zip(13,8,13,9) );
|
|
||||||
case 6: return ( zip(24,18,18,14) );
|
|
||||||
}
|
|
||||||
break; }
|
|
||||||
case 5: { switch (b) {
|
|
||||||
case 5: return ( zoom(13,8,13,8,8,3,8,3) );
|
|
||||||
case 6: return ( zip(24,18,18,13) );
|
|
||||||
}
|
|
||||||
break; }
|
|
||||||
case 6: { return ( zoom(13,7,13,7,24,18,24,18) );
|
|
||||||
break; }
|
|
||||||
}
|
|
||||||
|
|
||||||
} /* end: book0 */
|
|
||||||
book1( a,b ) int a, b; { /* mostly follows Becker */
|
|
||||||
switch (a) {
|
|
||||||
case 1: { switch (b) {
|
|
||||||
case 1: return ( zoom(8,7,8,7,6,5,6,5) );
|
|
||||||
case 2: return ( zip(13,11,6,5) );
|
|
||||||
case 3: return ( zip(8,5,6,5) );
|
|
||||||
case 4: return ( zip(13,9,6,5) );
|
|
||||||
case 5: return ( zip(13,8,6,5) );
|
|
||||||
case 6: return ( zip(13,7,8,7) );
|
|
||||||
}
|
|
||||||
break; }
|
|
||||||
case 2: { switch (b) {
|
|
||||||
case 2: return ( zoom(6,4,6,4,13,11,13,11) );
|
|
||||||
case 3: return ( zip(13,11,13,10) );
|
|
||||||
case 4: return ( zip(8,4,6,4) );
|
|
||||||
case 5: return ( zip(13,8,13,11) );
|
|
||||||
case 6: return ( zip(13,7,7,5) );
|
|
||||||
}
|
|
||||||
break; }
|
|
||||||
case 3: { switch (b) {
|
|
||||||
case 3: return ( zoom(13,10,13,10,8,5,8,5) );
|
|
||||||
case 4: return ( zip(13,10,13,9) );
|
|
||||||
case 5: return ( zip(13,8,8,5) );
|
|
||||||
case 6: return ( zip(13,7,13,10) );
|
|
||||||
}
|
|
||||||
break; }
|
|
||||||
case 4: { switch (b) {
|
|
||||||
case 4: return ( zoom(13,9,13,9,9,5,9,5) );
|
|
||||||
case 5: return ( zip(13,8,13,9) );
|
|
||||||
case 6: return ( zip(13,7,13,9) );
|
|
||||||
}
|
|
||||||
break; }
|
|
||||||
case 5: { switch (b) {
|
|
||||||
case 5: return ( zoom(13,8,13,8,8,3,8,3) );
|
|
||||||
case 6: return ( zip(13,7,13,8) );
|
|
||||||
}
|
|
||||||
break; }
|
|
||||||
case 6: { return ( zoom(13,7,13,7,24,18,24,18) );
|
|
||||||
break; }
|
|
||||||
}
|
|
||||||
|
|
||||||
} /* end: book1 */
|
|
||||||
book2( a,b ) int a, b; { /* mostly follows Becker */
|
|
||||||
switch (a) {
|
|
||||||
case 1: { switch (b) {
|
|
||||||
case 1: return ( zoom(8,7,8,7,6,5,6,5) );
|
|
||||||
case 2: return ( zip(13,11,24,23) );
|
|
||||||
case 3: return ( zip(8,5,6,5) );
|
|
||||||
case 4: return ( zip(13,9,24,23) );
|
|
||||||
case 5: return ( zip(13,8,24,23) );
|
|
||||||
case 6: return ( zip(13,7,8,7) );
|
|
||||||
}
|
|
||||||
break; }
|
|
||||||
case 2: { switch (b) {
|
|
||||||
case 2: return ( zoom(6,4,6,4,24,23,24,23) );
|
|
||||||
case 3: return ( zip(13,11,13,10) );
|
|
||||||
case 4: return ( zip(8,4,6,4) );
|
|
||||||
case 5: return ( zip(13,8,13,11) );
|
|
||||||
case 6: return ( zip(13,7,13,11) );
|
|
||||||
}
|
|
||||||
break; }
|
|
||||||
case 3: { switch (b) {
|
|
||||||
case 3: return ( zoom(13,10,13,10,10,7,10,7) );
|
|
||||||
case 4: return ( zip(13,10,13,9) );
|
|
||||||
case 5: return ( zip(13,8,8,5) );
|
|
||||||
case 6: return ( zip(13,7,13,10) );
|
|
||||||
}
|
|
||||||
break; }
|
|
||||||
case 4: { switch (b) {
|
|
||||||
case 4: return ( zoom(13,9,13,9,9,5,9,5) );
|
|
||||||
case 5: return ( zip(13,8,13,9) );
|
|
||||||
case 6: return ( zip(13,7,13,9) );
|
|
||||||
}
|
|
||||||
break; }
|
|
||||||
case 5: { switch (b) {
|
|
||||||
case 5: return ( zoom(13,8,13,8,8,3,8,3) );
|
|
||||||
case 6: return ( zip(13,7,13,8) );
|
|
||||||
}
|
|
||||||
break; }
|
|
||||||
case 6: { return ( zoom(13,7,13,7,24,18,24,18) );
|
|
||||||
break; }
|
|
||||||
}
|
|
||||||
|
|
||||||
} /* end: book2 */
|
|
||||||
|
|
||||||
|
|
||||||
/*====== MyMove ======*/
|
|
||||||
|
|
||||||
torve() {
|
|
||||||
if ( makeprime() ) { /* this will use doubles, if it can */
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if ( walkingprime() ) { /* i have six prime points, so run!!! */
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if ( dice[0] == dice[1] ) { /* this is too easy! */
|
|
||||||
if ( counterclock( kamikaze ) )
|
|
||||||
return;
|
|
||||||
if ( counterclock( dbuild ) ) /* claim new turf */
|
|
||||||
return;
|
|
||||||
if ( clockwise( run ) )
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if ( cleanup() ) { /* cover my single blot on prime points */
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if ( bearoff() ) { /* I'm ready, but you're in the back game! */
|
|
||||||
if ( counterclock( gohome ) )
|
|
||||||
return;
|
|
||||||
if ( clockwise( run ) )
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if ( clockwise( hitandrun ) )
|
|
||||||
return;
|
|
||||||
if ( matchup( natural ) )
|
|
||||||
return;
|
|
||||||
if ( clockwise( landonme ) )
|
|
||||||
return;
|
|
||||||
if ( counterclock( runnerup ) )
|
|
||||||
return;
|
|
||||||
if ( clockwise( scatter ) )
|
|
||||||
return;
|
|
||||||
if ( clockwise( run ) )
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
} /* end: torve */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
villiers() {
|
|
||||||
if ( makeprime() ) { /* this will use doubles, if it can */
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if ( walkingprime() ) { /* i have six prime points, so run!!! */
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if ( dice[0] == dice[1] ) { /* this is too easy! */
|
|
||||||
if ( counterclock( kamikaze ) )
|
|
||||||
return;
|
|
||||||
if ( counterclock( dbuild ) ) /* claim new turf */
|
|
||||||
return;
|
|
||||||
if ( clockwise( run ) )
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if ( cleanup() ) { /* cover my single blot on prime points */
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if ( bearoff() ) { /* I'm ready, but you're in the back game! */
|
|
||||||
if ( counterclock( gohome ) )
|
|
||||||
return;
|
|
||||||
if ( clockwise( run ) )
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if ( clockwise( foolsdemise ) )
|
|
||||||
return;
|
|
||||||
if ( clockwise( idareyou ) )
|
|
||||||
return;
|
|
||||||
if ( counterclock( covermine ) )
|
|
||||||
return;
|
|
||||||
if ( matchup( natural ) )
|
|
||||||
return;
|
|
||||||
if ( clockwise( landonme ) )
|
|
||||||
return;
|
|
||||||
if ( clockwise( runnerup ) )
|
|
||||||
return;
|
|
||||||
if ( clockwise( scatter ) )
|
|
||||||
return;
|
|
||||||
if ( clockwise( run ) )
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
} /* end: villiers */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
louisa() {
|
|
||||||
if ( makeprime() ) { /* this will use doubles, if it can */
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if ( walkingprime() ) { /* i have six prime points, so run!!! */
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if ( dice[0] == dice[1] ) { /* this is too easy! */
|
|
||||||
if ( counterclock( kamikaze ) )
|
|
||||||
return;
|
|
||||||
if ( counterclock( dbuild ) ) /* claim new turf */
|
|
||||||
return;
|
|
||||||
if ( clockwise( run ) )
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if ( cleanup() ) { /* cover my single blot on prime points */
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if ( bearoff() ) { /* I'm ready, but you're in the back game! */
|
|
||||||
if ( counterclock( gohome ) )
|
|
||||||
return;
|
|
||||||
if ( clockwise( run ) )
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if ( (!naked() && goodboard()) || yourfolly() ) {
|
|
||||||
if ( clockwise( hitandrun ) )
|
|
||||||
return;
|
|
||||||
if ( matchup( natural ) )
|
|
||||||
return;
|
|
||||||
if ( clockwise( landonme ) )
|
|
||||||
return;
|
|
||||||
if ( counterclock( runnerup ) )
|
|
||||||
return;
|
|
||||||
if ( clockwise( scatter ) )
|
|
||||||
return;
|
|
||||||
if ( clockwise( run ) )
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if ( clockwise( foolsdemise ) )
|
|
||||||
return;
|
|
||||||
if ( clockwise( idareyou ) )
|
|
||||||
return;
|
|
||||||
if ( counterclock( covermine ) )
|
|
||||||
return;
|
|
||||||
if ( matchup( natural ) )
|
|
||||||
return;
|
|
||||||
if ( clockwise( landonme ) )
|
|
||||||
return;
|
|
||||||
if ( clockwise( runnerup ) )
|
|
||||||
return;
|
|
||||||
if ( clockwise( scatter ) )
|
|
||||||
return;
|
|
||||||
if ( clockwise( run ) )
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} /* end: louisa */
|
|
||||||
|
|
||||||
|
|
||||||
mymove() {
|
|
||||||
int i, d;
|
|
||||||
|
|
||||||
if ( nomove() ) {
|
|
||||||
if (lookforit && (dice[0] != dice[1])) {
|
|
||||||
lookforit = FALSE;
|
|
||||||
puts("\008... ");
|
|
||||||
switch (level) {
|
|
||||||
case 0: { puts("Blocked!"); break; }
|
|
||||||
case 1: { puts("Well, no!"); break; }
|
|
||||||
case 2: { puts("Thurb!"); break; }
|
|
||||||
}
|
|
||||||
sleep(10);
|
|
||||||
restoreboard();
|
|
||||||
update();
|
|
||||||
|
|
||||||
/* put the high die in list zero */
|
|
||||||
d = dice[0]; dice[0] = dice[1]; dice[1] = d;
|
|
||||||
|
|
||||||
cantuse = ERROR; movesleft = 2; myturns = 1;
|
|
||||||
switch (level) {
|
|
||||||
case 0: { setchat("I move"); break; }
|
|
||||||
case 1: { setchat("Let's try"); break; }
|
|
||||||
case 2: { setchat("Move is"); break; }
|
|
||||||
}
|
|
||||||
debug(chatter);
|
|
||||||
prmchk = 12;
|
|
||||||
weasel();
|
|
||||||
/* the rules say, use both dice if you can, or */
|
|
||||||
/* the highest if one or the other but not both */
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
lookforit = TRUE;
|
|
||||||
strcat(chatter," and now I'm blocked ");
|
|
||||||
myturns = movesleft = 0;
|
|
||||||
} }
|
|
||||||
else if ( book() ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if ( pending.flag ) {
|
|
||||||
lurch( pending.fr, pending.to, 1 );
|
|
||||||
clrpend();
|
|
||||||
}
|
|
||||||
else if ( endgame() ) { /* very solid tactics here!! */
|
|
||||||
if ( clockwise( gohome ) )
|
|
||||||
return;
|
|
||||||
if ( clockwise( nobackgammon ) ) /* no excuse! */
|
|
||||||
return;
|
|
||||||
if ( clockwise( crosstable ) )
|
|
||||||
return;
|
|
||||||
if ( clockwise( fiftytworule ) )
|
|
||||||
return;
|
|
||||||
if ( clockwise( scatter ) )
|
|
||||||
return;
|
|
||||||
if ( clockwise( run ) )
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if ( point[ MYBAR ].stones > 0 ) { /* I'm on the bar! */
|
|
||||||
if ( clockwise( hitandrun ) ) /* wreak havoc, please */
|
|
||||||
return;
|
|
||||||
if ( clockwise( run ) ) /* note: uses low die first */
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else switch (level) {
|
|
||||||
case 0: { villiers(); break; }
|
|
||||||
case 1: { louisa(); break; }
|
|
||||||
case 2: { torve(); break; }
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} /* end: mymove */
|
|
||||||
|
|
||||||
/*------------------------------*/
|
|
||||||
/* end of the GAMEPLAN.C module */
|
|
||||||
/*------------------------------*/
|
|
||||||
|
|
@ -1,42 +0,0 @@
|
|||||||
/* GAMEPLAN.HDR */
|
|
||||||
|
|
||||||
/*================================================================*/
|
|
||||||
/* change nothing in this file */
|
|
||||||
/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
|
|
||||||
|
|
||||||
#define TRUE 1
|
|
||||||
#define FALSE 0
|
|
||||||
#define ME 1
|
|
||||||
#define YU 2
|
|
||||||
#define YRBAR 0
|
|
||||||
#define MYBAR 25
|
|
||||||
#define YRHOME 26
|
|
||||||
#define MYHOME 27
|
|
||||||
#define ERROR 999
|
|
||||||
#define MYLEVEL 2
|
|
||||||
|
|
||||||
extern int list[2][28]; /* two dice, two lists */
|
|
||||||
|
|
||||||
extern struct board {
|
|
||||||
int stones, /* number of stones on that point */
|
|
||||||
owner, /* and whose they are */
|
|
||||||
x,y, /* x and y coordinates of point base */
|
|
||||||
lastx,lasty, /* last location drawn on this point */
|
|
||||||
cx,cy; /* coordinates for column numbers */
|
|
||||||
}
|
|
||||||
point[28], bdsave[28]; /* 24 points, plus 2 bars, 2 homes */
|
|
||||||
|
|
||||||
extern struct { int cube, whosecube; } doubles;
|
|
||||||
|
|
||||||
extern struct { int fr,to,flag; } pending;
|
|
||||||
|
|
||||||
extern int level, dice[2], myscore, yrscore, player, movesleft, cantuse,
|
|
||||||
myturns, swapped, tswap, deciding, expert, tone, show, moremsgline,
|
|
||||||
firstmove, helpdisabled, yrdice, lookforit, startcubevalue;
|
|
||||||
|
|
||||||
extern char *chatter[80];
|
|
||||||
|
|
||||||
/*----------------------------------------------*/
|
|
||||||
/* end of header -- change NOTHING in this file */
|
|
||||||
/*----------------------------------------------*/
|
|
||||||
|
|
@ -1,541 +0,0 @@
|
|||||||
/*
|
|
||||||
MYLIB2.C
|
|
||||||
|
|
||||||
These routines are CONDITIONALLY compiled; i.e., only as needed.
|
|
||||||
|
|
||||||
----------------------------------------------------------------------
|
|
||||||
Incorporates special mods used by my Backgammon game, BACKGMMN.C etc.
|
|
||||||
----------------------------------------------------------------------
|
|
||||||
|
|
||||||
A set of common I/O functions that seem to turn up a lot in my programs,
|
|
||||||
including terminal functions for Kaypro 10, 4'84, 2X etc.
|
|
||||||
|
|
||||||
Uses Software Toolworks' C/80 3.1 compiler. Place #include "mylib2.c" at the
|
|
||||||
end of your source file for correct CONDITIONAL COMPILATION.
|
|
||||||
|
|
||||||
David C. Oshel
|
|
||||||
1219 Harding Ave.
|
|
||||||
Ames, Iowa 50010
|
|
||||||
|
|
||||||
Last modified: March 25, 1986
|
|
||||||
|
|
||||||
-----------------------------------------------------------------------------
|
|
||||||
** WARNING ** These routines use direct console IO, bdos function 6!
|
|
||||||
|
|
||||||
YOU MUST CALL INIT_LIB() BEFORE USING THESE ROUTINES!
|
|
||||||
|
|
||||||
======= UTILITIES =======
|
|
||||||
|
|
||||||
* init_lib() - CALL THIS FIRST, OR THE RESULT WILL BE VERY STRANGE!
|
|
||||||
*
|
|
||||||
* puts(p) - unformatted print, e.g., puts("Hello, sailor!\n");
|
|
||||||
* gets(p,max) - printable input only, no prompt character
|
|
||||||
*
|
|
||||||
* ask(p) - demand Yes or No response to question p
|
|
||||||
* random() - effective random 16-bit integer IFF gets() is used
|
|
||||||
* sleep(n) - sleep n/10ths of a second, roughly (from C80.LIB)
|
|
||||||
* rollup() - roll up 23 lines of screen
|
|
||||||
* ONscript() - printer echo ON for output via puts, chrout
|
|
||||||
* OFFscript() - printer echo OFF for output via puts, chrout
|
|
||||||
* ONinterrupt() - Ctl-C, Ctl-B cause program exit
|
|
||||||
* OFFinterrupt() - Ctl-C, Ctl-B cause comedy
|
|
||||||
* hide_input(p,max) - like gets, but used when entering passwords
|
|
||||||
* chrout(c) - if scripting, echo output also to LST:
|
|
||||||
* putscreen(p) - like puts, but always and only to screen
|
|
||||||
|
|
||||||
|
|
||||||
======= KAYPRO 10 TERMINAL/VIDEO FUNCTIONS =======
|
|
||||||
|
|
||||||
* gotoxy(x,y) - 0,0 is top left, horz <= 79 precedes vert <= 24,
|
|
||||||
* where 0,24 is on the 25th, status, line.
|
|
||||||
* beep() - terminal bell
|
|
||||||
* home() - home cursor, do not clear screen
|
|
||||||
* clr_screen() - home and clear
|
|
||||||
*
|
|
||||||
* shadow_box(h,v,x1,y1,x2,y2) - like box, but with shadow, calls box
|
|
||||||
* box(tlx,tly,brx,bry) - draw a line box, coords: topleft XY, bottomright XY
|
|
||||||
* note that box calls ldraw(x1,y1,x2,y2), below
|
|
||||||
*
|
|
||||||
* clr_lend() - clear from cursor to end of line
|
|
||||||
* clr_send() - clear from cursor to end of screen
|
|
||||||
* rev_vid(),
|
|
||||||
* nor_vid() - reverse field
|
|
||||||
* dim_vid(),
|
|
||||||
* bri_vid() - low/high intensity
|
|
||||||
* on_blink(),
|
|
||||||
* off_blink() - blinking chars
|
|
||||||
* ul_start(),
|
|
||||||
* ul_stop() - start/stop underline
|
|
||||||
* save_cursor(),
|
|
||||||
* retn_cursor() - remember/restore current cursor location
|
|
||||||
* ins_line(),
|
|
||||||
* del_line() - insert/delete screen text line
|
|
||||||
* on_cursor(),
|
|
||||||
* off_cursor() - hide/show cursor
|
|
||||||
* vm_on(),
|
|
||||||
* vm_off() - "Video Mode" commands
|
|
||||||
* pixel(x,y) - draw pixel at x,y (video coords, x <= 159, y <= 99)
|
|
||||||
* no_pixel(x,y) - erase pixel at x,y
|
|
||||||
* ldraw(x1,y1,x2,y2) - draw/ erase graphics line, see discussion for box
|
|
||||||
* lwipe(x1,y1,x2,y2) - range for video coordinates as for pixel
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef TRUE
|
|
||||||
#define TRUE 1
|
|
||||||
#endif
|
|
||||||
#ifndef FALSE
|
|
||||||
#define FALSE 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* hide this here so's not to worry about it elsewhere */
|
|
||||||
/* "printf.c" collides with one of these, can't remember which */
|
|
||||||
/* puts() takes longer to write, but executes faster */
|
|
||||||
extern char Cmode, IOpread[4], IOpwrit[4], IOpeof[4];
|
|
||||||
|
|
||||||
/* make these known only to what follows */
|
|
||||||
static int MYbstout, MYscrtp, MYretnirp; /* odd names mark semi-private */
|
|
||||||
static unsigned RNDloc; /* effective random location, bumped by gets() */
|
|
||||||
/* and scrambled when the LCG random() is called */
|
|
||||||
/* makes a decent algorithm for interactive games */
|
|
||||||
|
|
||||||
|
|
||||||
#ifneed init_lib
|
|
||||||
init_lib() {
|
|
||||||
|
|
||||||
MYretnirp = fopen("LST:","w");
|
|
||||||
OFFscript();
|
|
||||||
ONinterrupt();
|
|
||||||
Cmode = 0;
|
|
||||||
IOpread[0] = 6; IOpwrit[0] = 6;
|
|
||||||
|
|
||||||
} /* end: init_lib */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifneed random
|
|
||||||
random() { /* depends on effective random location spun by gets() */
|
|
||||||
|
|
||||||
RNDloc = 2053 * RNDloc + 13849;
|
|
||||||
return (RNDloc);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifneed ONscript
|
|
||||||
ONscript() {
|
|
||||||
|
|
||||||
MYscrtp = TRUE;
|
|
||||||
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifneed OFFscript
|
|
||||||
OFFscript() {
|
|
||||||
|
|
||||||
MYscrtp = FALSE;
|
|
||||||
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifneed ONinterrupt
|
|
||||||
ONinterrupt() {
|
|
||||||
|
|
||||||
MYbstout = TRUE;
|
|
||||||
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifneed OFFinterrupt
|
|
||||||
OFFinterrupt() {
|
|
||||||
|
|
||||||
MYbstout = FALSE;
|
|
||||||
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifneed ask
|
|
||||||
ask(p) char *p; {
|
|
||||||
|
|
||||||
char ch, resp[2];
|
|
||||||
|
|
||||||
loo: puts(p);
|
|
||||||
gets(resp,1);
|
|
||||||
ch = toupper( *resp );
|
|
||||||
if ( !( ch == 'Y' || ch == 'N' )) {
|
|
||||||
puts("Please answer the question, Yes or No.\n");
|
|
||||||
goto loo;
|
|
||||||
}
|
|
||||||
return (ch == 'Y');
|
|
||||||
|
|
||||||
} /* end: ask */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifneed rollup
|
|
||||||
rollup() {
|
|
||||||
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i=0; i<23; i++) puts("\n");
|
|
||||||
|
|
||||||
} /* end: rollup */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifneed sleep
|
|
||||||
sleep( n ) int n; { /* sleep for n/10 seconds, 0 <= n < 256 */
|
|
||||||
|
|
||||||
n; /* get n into HL */
|
|
||||||
#asm
|
|
||||||
MOV B,L ;delay B/10ths of a second
|
|
||||||
__DL0: MVI A,100 ;100 milliseconds, 1/10 second
|
|
||||||
__DL1: MVI C,249 ;1 millisecond per unit of A at 4 MHz
|
|
||||||
__DL2: DCR C ;Leventhal, Z80 Assembly Language Programming
|
|
||||||
JNZ __DL2
|
|
||||||
DCR A
|
|
||||||
JNZ __DL1
|
|
||||||
DCR B
|
|
||||||
JNZ __DL0 ;on exit, HL has FALSE if n was 0, else TRUE
|
|
||||||
#endasm
|
|
||||||
} /* end: sleep */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/*========================================*/
|
|
||||||
/* GETS(p, maxinput) */
|
|
||||||
/* Local getline function with special *---* WARNING: */
|
|
||||||
/* input handling, 1 <= len <= maxinput *---* Execute INIT_LIB() first !! */
|
|
||||||
/* Updates effective random, RNDloc, */
|
|
||||||
/* Forces input from CONSOLE only! */
|
|
||||||
/*========================================*/
|
|
||||||
|
|
||||||
#ifneed gets
|
|
||||||
gets(p,maxinput) char *p; int maxinput; {
|
|
||||||
|
|
||||||
/* This function depends on BDOS Function #6. Init_lib() sets Cmode=0 and
|
|
||||||
IOpread[0]=6 and IOpwrit[0]=6 (courtesy of and peculiar to C/80 3.1)
|
|
||||||
YOU must ensure that the target string is long enough to collect the
|
|
||||||
entire maximum input allowed and specified, INCLUDING FINAL NULL! */
|
|
||||||
|
|
||||||
static int len;
|
|
||||||
static char ch;
|
|
||||||
|
|
||||||
len = -1;
|
|
||||||
if (maxinput < 1 || maxinput > 127) maxinput = 79;
|
|
||||||
|
|
||||||
/*--------------------------------*/
|
|
||||||
/* SPECIAL ROUTINE FOR BACKGAMMON */
|
|
||||||
/*--------------------------------*/
|
|
||||||
|
|
||||||
loo: while ( !(ch = getc(0)) ) acg(); /* keep the game lively */
|
|
||||||
|
|
||||||
if (len < 0) len = 0; /* don't destroy prompt by backing up */
|
|
||||||
if (ch == '\n') { /* end of line? don't store newline */
|
|
||||||
*p = '\0'; /* mark it with a B for baby and me */
|
|
||||||
/* chrout('\n'); */ /* but DON'T echo newline */
|
|
||||||
return ( len ); /* <--- HERE IS THE FUNCTION EXIT! */
|
|
||||||
}
|
|
||||||
else if (ch == '\b' || ch == 0x7F) { /* backspace? rubout? */
|
|
||||||
if (len--) { /* where's the prompt? */
|
|
||||||
puts("\008 \008"); /* we're ok, echo erase */
|
|
||||||
p--; /* delete from string */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*--------------------------------*/
|
|
||||||
/* SPECIAL ROUTINE FOR BACKGAMMON */
|
|
||||||
/*--------------------------------*/
|
|
||||||
|
|
||||||
else if (ch == '\003') { /* user bailout key is Ctrl-C, not ESC */
|
|
||||||
if (MYbstout) exit();
|
|
||||||
else {
|
|
||||||
haltgame(); /* sets whofirst flag and does jumpjack() */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (ch == '\025' || ch == '\030') { /* Ctl-U, Ctl-X */
|
|
||||||
while (len--) {
|
|
||||||
p--;
|
|
||||||
puts("\008 \008");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (len == maxinput) { /* test specials before testing len */
|
|
||||||
chrout('\007');
|
|
||||||
}
|
|
||||||
else if (ch > 31 && ch < 127) { /* printable char? */
|
|
||||||
chrout(ch); /* yes, echo it */
|
|
||||||
*p++ = ch; /* collect it */
|
|
||||||
len++; /* keep track of it */
|
|
||||||
}
|
|
||||||
else { /* control chars? */
|
|
||||||
chrout('\007');
|
|
||||||
}
|
|
||||||
goto loo;
|
|
||||||
|
|
||||||
} /* end: gets */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifneed hide_input
|
|
||||||
hide_input(s,len) char *s; int len; {
|
|
||||||
|
|
||||||
/* receive at most len chars in s buffer,
|
|
||||||
terminate string with zero,
|
|
||||||
but echo each char with 1, 2, or 3 meaningless dots */
|
|
||||||
|
|
||||||
char ch; int num;
|
|
||||||
|
|
||||||
if ((len < 1) || (len > 127)) len = 127;
|
|
||||||
num = 0;
|
|
||||||
for (;;) { /* forever */
|
|
||||||
while ((ch = getc(0)) == 0) /* bdos 6 does not wait, so we do */
|
|
||||||
;
|
|
||||||
if ((ch == '\r') || (ch == '\n') || (num++ > len)) {
|
|
||||||
/* not sure what the CR key actually is to bdos 6 & C/80 */
|
|
||||||
*s++ = '\0';
|
|
||||||
return; /* this way out */
|
|
||||||
}
|
|
||||||
if ((num % 2) == 0) putc('.',0); /* deception, illusion */
|
|
||||||
if ((num % 5) == 0) putc('.',0);
|
|
||||||
putc('.',0);
|
|
||||||
*s++ = ch;
|
|
||||||
}
|
|
||||||
|
|
||||||
} /* end: hide_input */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------ kpro stuff -------------------------*/
|
|
||||||
|
|
||||||
#ifneed shadow_box
|
|
||||||
/* like box, but with horizontal & vertical displacement for shadow */
|
|
||||||
shadow_box(h,v,x1,y1,x2,y2) int h,v,x1,y1,x2,y2;
|
|
||||||
{
|
|
||||||
box(x1+h,y1+v,x2+h,y2+v); /* draw the shadow */
|
|
||||||
box(x1,y1,x2,y2); /* draw the box */
|
|
||||||
ldraw(x1+h,y1+v,x1,y1); /* draw the corners */
|
|
||||||
ldraw(x2+h,y2+v,x2,y2);
|
|
||||||
ldraw(x2+h,y1+v,x2,y1);
|
|
||||||
ldraw(x1+h,y2+v,x1,y2);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifneed box
|
|
||||||
/* parameters are topleft X,Y and bottomright X,Y
|
|
||||||
X ranges from 0 to 159, Y ranges from 0 to 99, top left is 0,0
|
|
||||||
*/
|
|
||||||
box(x1,y1,x2,y2) int x1,y1,x2,y2; {
|
|
||||||
ldraw(x1,y1,x1,y2);
|
|
||||||
ldraw(x1,y2,x2,y2); /* appears to draw the box anticlockwise */
|
|
||||||
ldraw(x2,y1,x2,y2);
|
|
||||||
ldraw(x1,y1,x2,y1);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifneed gotoxy
|
|
||||||
gotoxy (xpos,ypos) int xpos,ypos; { /* 0,0 is top left corner */
|
|
||||||
putscreen("\033=");
|
|
||||||
putc(ypos+' ',0);
|
|
||||||
putc(xpos+' ',0);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifneed beep
|
|
||||||
beep() { putc(7,0); } /* send bell character */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifneed home
|
|
||||||
home() { putc(30,0); } /* home cursor to top left */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifneed clr_screen
|
|
||||||
clr_screen() { putc(26,0); } /* home and erase screen */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifneed clr_lend
|
|
||||||
clr_lend() { putc(24,0); } /* clear to end of line */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifneed clr_send
|
|
||||||
clr_send() { putc(23,0); } /* clear to end of screen */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifneed rev_vid
|
|
||||||
rev_vid() { putscreen ("\033B0"); } /* reverse background */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifneed nor_vid
|
|
||||||
nor_vid() { putscreen ("\033C0"); }
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifneed dim_vid
|
|
||||||
dim_vid() { putscreen ("\033B1"); } /* low intensity */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifneed bri_vid
|
|
||||||
bri_vid() { putscreen ("\033C1"); }
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifneed on_blink
|
|
||||||
on_blink() { putscreen ("\033B2"); } /* blinking characters */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifneed off_blink
|
|
||||||
off_blink() { putscreen ("\033C2"); }
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifneed ul_start
|
|
||||||
ul_start() { putscreen ("\033B3"); } /* underline */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifneed ul_stop
|
|
||||||
ul_stop() { putscreen ("\033C3"); }
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifneed save_cursor
|
|
||||||
save_cursor() { putscreen ("\033B6"); } /* remember cursor position */
|
|
||||||
#endif
|
|
||||||
#ifneed retn_cursor
|
|
||||||
retn_cursor() { putscreen ("\033C6"); } /* return to remembered pos */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifneed on_status
|
|
||||||
on_status() { putscreen ("\033B7"); } /* status line preservation on */
|
|
||||||
#endif
|
|
||||||
#ifneed off_status
|
|
||||||
off_status() { putscreen ("\033C7"); }
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifneed ins_line
|
|
||||||
ins_line() { /* insert text line */
|
|
||||||
putscreen("\033R");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifneed del_line
|
|
||||||
del_line() { /* delete text line */
|
|
||||||
putscreen("\033E");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifneed on_cursor
|
|
||||||
on_cursor() { putscreen ("\033B4"); } /* (in)visible cursor */
|
|
||||||
#endif
|
|
||||||
#ifneed off_cursor
|
|
||||||
off_cursor() { putscreen ("\033C4"); }
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Video Mode ON/OFF: video WORD, 8 bit video if 15 and 7 are both high */
|
|
||||||
/* VM-ON 10000001 11111111 VM-OFF */
|
|
||||||
/* ^video ^x^video */
|
|
||||||
/* otherwise, video BYTE, high bit 7 interprets bits 0-6 as screen dots */
|
|
||||||
/* 11111111 */
|
|
||||||
/* ^video */
|
|
||||||
/* e.g., */
|
|
||||||
/* Non-VideoMode VideoMode */
|
|
||||||
/* xx 1 11:0 where % is 1 01:0 1 11:0 xx */
|
|
||||||
/* xx 3 11 2 the video 3 00 2 3 11 2 xx */
|
|
||||||
/* xx 5 11 4 flag bit, 5 00 4 5 11 4 xx */
|
|
||||||
/* x 7:%1 6 x is pixel 7:%0 6 7:%1 6 xx */
|
|
||||||
/* ^ ^ ^ */
|
|
||||||
/* to set the pixels, first do a gotoxy to character screen position */
|
|
||||||
/* this mode is faster than Pixel ON/OFF if values are drawn from table */
|
|
||||||
#ifneed vm_on
|
|
||||||
vm_on() { putscreen ("\033B5"); } /* video mode on */
|
|
||||||
#endif
|
|
||||||
#ifneed vm_off
|
|
||||||
vm_off() { putscreen ("\033C5"); }
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifneed pixel
|
|
||||||
pixel(x,y) int x,y; { /* x <= 159, y <= 99 */
|
|
||||||
putscreen("\033*");
|
|
||||||
putc(y+' ',0); putc(x+' ',0);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifneed no_pixel
|
|
||||||
no_pixel(x,y) int x,y; { /* x <= 159, y <= 99 */
|
|
||||||
putscreen("\033 ");
|
|
||||||
putc(y+' ',0); putc(x+' ',0);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifneed ldraw
|
|
||||||
/* use x1 <= x2, y1 <= y2, order is significant (Kaypro bug?) */
|
|
||||||
ldraw(x1,y1,x2,y2) int x1,x2,y1,y2; { /* x <= 159, y <= 99 */
|
|
||||||
putscreen("\033L");
|
|
||||||
putc(y1+' ',0); putc(x1+' ',0);
|
|
||||||
putc(y2+' ',0); putc(x2+' ',0);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifneed lwipe
|
|
||||||
lwipe(x1,y1,x2,y2) int x1,x2,y1,y2; { /* x <= 159, y <= 99 */
|
|
||||||
putscreen("\033D");
|
|
||||||
putc(y1+' ',0); putc(x1+' ',0);
|
|
||||||
putc(y2+' ',0); putc(x2+' ',0);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifneed putscreen
|
|
||||||
putscreen(p) char *p; {
|
|
||||||
|
|
||||||
while (*p) putc(*p++,0);
|
|
||||||
|
|
||||||
} /* end: putscreen */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifneed puts
|
|
||||||
puts(p) char *p; {
|
|
||||||
|
|
||||||
while (*p) chrout(*p++);
|
|
||||||
|
|
||||||
} /* end: puts */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifneed chrout
|
|
||||||
chrout(c) char c; { /* SPECIAL FOR SCRIPT OPTION WITH LST: */
|
|
||||||
|
|
||||||
putc(c,0);
|
|
||||||
if ( MYscrtp ) putc(c,MYretnirp);
|
|
||||||
|
|
||||||
} /* end: chrout */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* end: MYLIB.C */
|
|
||||||
|
|
||||||
|
|
@ -1,56 +0,0 @@
|
|||||||
|
|
||||||
GAMNIV20.LBR
|
|
||||||
------------
|
|
||||||
Gammon IV, Version 2.0, April 1, 1986. Full-screen backgammon for CP/M.
|
|
||||||
|
|
||||||
This is the April Fool's Day (1986) edition of Gammon IV, the first major
|
|
||||||
update in many months.
|
|
||||||
|
|
||||||
BACKGMMN.COM is the compiled and ready-to-run object file. It requires
|
|
||||||
either an ADM-3A compatible terminal ("old" Kaypro) or a screen with video
|
|
||||||
characteristics exactly like the Kaypro 2X, 4'84 or 10. However, this
|
|
||||||
version has the same CRT Module as formerly, including a clearly-marked user
|
|
||||||
patch area for non-Kaypro terminals.
|
|
||||||
|
|
||||||
Improvements for Version 2.0 include:
|
|
||||||
|
|
||||||
a) Several bugs and poltergeists, especially in the Arrange command, have
|
|
||||||
been completely exorcised. No bugs have been found in the Play command
|
|
||||||
for months; but, as before, Gammon IV will not invariably recognize a
|
|
||||||
forced move, either in your play or in its own. Gammon IV knows and
|
|
||||||
obeys all other official rules of backgammon.
|
|
||||||
|
|
||||||
b) There are no "hidden" commands anymore. All commands are now shown in
|
|
||||||
the command lines, including X(pert and G(raphic. The G(raphic command
|
|
||||||
turns on the Kaypro video-able display.
|
|
||||||
|
|
||||||
c) Input error handling now documents the BAR, HOME and HELP commands, so
|
|
||||||
first-time players do not need to read anything else in order to play
|
|
||||||
the game successfully. The X(pert mode dispenses with these messages,
|
|
||||||
so X(pert actually does mean expert, now!
|
|
||||||
|
|
||||||
d) The "break" command is Control-C again, instead of ESCAPE. It was
|
|
||||||
all too easy to hit ESC instead of 1 on the Kaypro keyboard, leading to
|
|
||||||
an inadvertently paused game.
|
|
||||||
|
|
||||||
e) The sanction against cheating (your opponent became Torve) has been
|
|
||||||
removed.
|
|
||||||
|
|
||||||
f) If the cube is doubled during the opening rolloff to see who goes
|
|
||||||
first, and the cube value reaches 8, additional pairs on the dice
|
|
||||||
have no further effect. The cube's opening value will not go above 8.
|
|
||||||
|
|
||||||
The computer's three styles of play have not been changed. Judging from the
|
|
||||||
feedback I've received, Gammon IV plays acceptably well at the current
|
|
||||||
levels. All information needed to re-compile the program is included in the
|
|
||||||
BACKGMMN.C file, including the details of C/80 3.1 configuration. The
|
|
||||||
compile and link steps are governed by BACKGMMN.SUB.
|
|
||||||
|
|
||||||
This program is in the public domain, so distribute it freely.
|
|
||||||
|
|
||||||
Enjoy!
|
|
||||||
|
|
||||||
David C. Oshel
|
|
||||||
1219 Harding Ave.
|
|
||||||
Ames, Iowa 50010
|
|
||||||
|
|
1968
backgmmn.c
1968
backgmmn.c
File diff suppressed because it is too large
Load Diff
BIN
backgmmn.com
BIN
backgmmn.com
Binary file not shown.
@ -1,8 +0,0 @@
|
|||||||
era *.bak
|
|
||||||
era *.mac
|
|
||||||
era backgmmn.rel
|
|
||||||
era gameplan.rel
|
|
||||||
era backgmmn.com
|
|
||||||
era backgmmn.mac
|
|
||||||
era gameplan.mac
|
|
||||||
|
|
13
bgmake.sub
13
bgmake.sub
@ -1,13 +0,0 @@
|
|||||||
era *.bak
|
|
||||||
era *.mac
|
|
||||||
era backgmmn.rel
|
|
||||||
era gameplan.rel
|
|
||||||
era backgmmn.com
|
|
||||||
c -m backgmmn
|
|
||||||
m80 =backgmmn
|
|
||||||
era backgmmn.mac
|
|
||||||
c -m gameplan
|
|
||||||
m80 =gameplan
|
|
||||||
era gameplan.mac
|
|
||||||
l80 backgmmn,gameplan,stdlib/s,clibrary/s,backgmmn/n/e
|
|
||||||
|
|
866
gameplan.c
866
gameplan.c
@ -1,866 +0,0 @@
|
|||||||
|
|
||||||
/* Gammon IV, by David C. Oshel, Ames, Iowa */
|
|
||||||
|
|
||||||
/*--------------------------------------------------------------------*/
|
|
||||||
/* GAMEPLAN.C -- separately compiled module, contains the tactics and */
|
|
||||||
/* strategy for making the computer's move in Gammon IV */
|
|
||||||
/* BACKGMMN.REL calls MyMove(), MyMove() calls topstone */
|
|
||||||
/* and movestone and a few others. Uses the globals in */
|
|
||||||
/* GAMEPLAN.HDR quite heavily. Bgversion declared here */
|
|
||||||
/*--------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#include "gameplan.hdr" /* contains external, global declarations */
|
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------*/
|
|
||||||
/* */
|
|
||||||
/* Bgversion is an external reference in the main module. Use this string */
|
|
||||||
/* to take credit for a decent gameplaying algorithm if you find one! */
|
|
||||||
/* */
|
|
||||||
char *bgversion = ".20 -April 1, 1986- by David C. Oshel";
|
|
||||||
/*....v....1....v....2....v....3....v...*/
|
|
||||||
/* just 38 characters for version info! */
|
|
||||||
/* */
|
|
||||||
/*-------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
|
|
||||||
/*=============================================*/
|
|
||||||
/* M Y M O V E */
|
|
||||||
/*=============================================*/
|
|
||||||
|
|
||||||
|
|
||||||
naked() { /* am I leaving too many blots? */
|
|
||||||
static int i, clink;
|
|
||||||
i = 24; clink = 0;
|
|
||||||
while (i) {
|
|
||||||
if (point[i].stones == 1 && point[i].owner == ME) clink++;
|
|
||||||
i--;
|
|
||||||
}
|
|
||||||
return (clink > 2);
|
|
||||||
} /* end: naked */
|
|
||||||
|
|
||||||
|
|
||||||
yourfolly() { /* look for lotsa blots in your inner table */
|
|
||||||
static int i, clink;
|
|
||||||
i = 18; clink = 0;
|
|
||||||
while (i < 25) {
|
|
||||||
if (point[i].owner == YU && point[i].stones == 1)
|
|
||||||
clink++;
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
return (clink >= 3);
|
|
||||||
} /* end: yourfolly */
|
|
||||||
|
|
||||||
|
|
||||||
goodboard() { /* look for four made points near my inner table */
|
|
||||||
static int i, clank, clink;
|
|
||||||
i = 9; clank = 0;
|
|
||||||
while (i > 3) {
|
|
||||||
if (point[i].owner == ME && point[i].stones > 1) clank++;
|
|
||||||
i--;
|
|
||||||
}
|
|
||||||
if (clank > 4) return (TRUE); /* bar is nearly blocked */
|
|
||||||
|
|
||||||
i = 6; clank = clink = 0;
|
|
||||||
while (i) {
|
|
||||||
if (point[i].owner != ME)
|
|
||||||
;
|
|
||||||
else if (point[i].stones == 1) clink++; else clank++;
|
|
||||||
i--;
|
|
||||||
}
|
|
||||||
return (clank > 3 && clink < 2);
|
|
||||||
} /* end: goodboard */
|
|
||||||
|
|
||||||
|
|
||||||
bearoff() {
|
|
||||||
return (topstone(ME) < 7);
|
|
||||||
} /* end: bearoff */
|
|
||||||
|
|
||||||
|
|
||||||
scanahead( from ) int from; {
|
|
||||||
static int count;
|
|
||||||
|
|
||||||
count = 0;
|
|
||||||
while (--from > 0) {
|
|
||||||
++count;
|
|
||||||
if ( point[ from ].owner == YU ) return (count);
|
|
||||||
}
|
|
||||||
return (7);
|
|
||||||
|
|
||||||
} /* end: scanahead */
|
|
||||||
|
|
||||||
|
|
||||||
endgame() { /* Is no strategy required from here on in? */
|
|
||||||
return ( (25 - topstone(YU)) > topstone(ME) );
|
|
||||||
} /* end: endgame */
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------*/
|
|
||||||
/* MATCHUP */
|
|
||||||
/* */
|
|
||||||
/* 2-stone functions that force the choice of the next move. */
|
|
||||||
/* These are the HEART and SOUL of this backgammon algorithm! */
|
|
||||||
/*------------------------------------------------------------*/
|
|
||||||
|
|
||||||
setpend( from, to ) int from, to; {
|
|
||||||
pending.fr = from;
|
|
||||||
pending.to = to;
|
|
||||||
pending.flag = TRUE;
|
|
||||||
} /* end: setpend */
|
|
||||||
|
|
||||||
|
|
||||||
clrpend() {
|
|
||||||
pending.flag = FALSE;
|
|
||||||
} /* end: clrpend */
|
|
||||||
|
|
||||||
|
|
||||||
natural(f1,t1,f2,t2) int f1,t1,f2,t2; {
|
|
||||||
clrpend();
|
|
||||||
if (point[t2].stones == 1 && t1 == f2) setpend(f2,t2);
|
|
||||||
return (pending.flag);
|
|
||||||
} /* end: natural */
|
|
||||||
|
|
||||||
|
|
||||||
matchup( test4 ) int (* test4)(); {
|
|
||||||
static int i, j, ti, tj;
|
|
||||||
|
|
||||||
if ( pending.flag ) return (FALSE); /* this is probably redundant */
|
|
||||||
|
|
||||||
for (i = 1; i < 26; i++) {
|
|
||||||
ti = list[0][i];
|
|
||||||
if ( ti == ERROR ) goto zoo;
|
|
||||||
for (j = 1; j < 26; j++) {
|
|
||||||
tj = list[1][j];
|
|
||||||
if ( tj == ERROR ) goto voo;
|
|
||||||
if ( (* test4)( i, ti, j, tj ) ) {
|
|
||||||
lurch( i, ti, 0);
|
|
||||||
return (TRUE);
|
|
||||||
}
|
|
||||||
voo: ;
|
|
||||||
}
|
|
||||||
zoo: ;
|
|
||||||
}
|
|
||||||
return (FALSE);
|
|
||||||
|
|
||||||
} /* end: matchup */
|
|
||||||
|
|
||||||
|
|
||||||
matchhi( test4 ) int (* test4)(); {
|
|
||||||
static int i, j, ti, tj;
|
|
||||||
|
|
||||||
if ( pending.flag ) return (FALSE); /* this is probably redundant */
|
|
||||||
|
|
||||||
for (i = 1; i < 26; i++) {
|
|
||||||
ti = list[1][i];
|
|
||||||
if ( ti == ERROR ) goto zoo;
|
|
||||||
for (j = 1; j < 26; j++) {
|
|
||||||
tj = list[0][j];
|
|
||||||
if ( tj == ERROR ) goto voo;
|
|
||||||
if ( (* test4)( i, ti, j, tj ) ) {
|
|
||||||
lurch( i, ti, 1);
|
|
||||||
return (TRUE);
|
|
||||||
}
|
|
||||||
voo: ;
|
|
||||||
}
|
|
||||||
zoo: ;
|
|
||||||
}
|
|
||||||
return (FALSE);
|
|
||||||
|
|
||||||
} /* end: matchhi */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*--------------------------------------------------------*/
|
|
||||||
/* CLOCKWISE and COUNTERCLOCK */
|
|
||||||
/* */
|
|
||||||
/* the rest of these are single-stone decisions based on */
|
|
||||||
/* rules of thumb, board-scanning functions */
|
|
||||||
/*--------------------------------------------------------*/
|
|
||||||
|
|
||||||
plainstupid( from ) int from; { /* don't break a safe point */
|
|
||||||
return (from < 13 && (point[from].stones == 2 && scanahead(from) < 7));
|
|
||||||
} /* end: plainstupid */
|
|
||||||
|
|
||||||
|
|
||||||
unwise( innertablept ) int innertablept; {
|
|
||||||
/* if it's a hit, just for god's sake don't put him on the bar!! */
|
|
||||||
if ( innertablept < 7 ) {
|
|
||||||
if (point[ innertablept ].owner == YU ||
|
|
||||||
point[ YRBAR ].stones > 0)
|
|
||||||
return (TRUE);
|
|
||||||
}
|
|
||||||
return(FALSE);
|
|
||||||
} /* end: unwise */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
covermine( from, to ) int from, to; {
|
|
||||||
if ( from < 8 ) return(FALSE);
|
|
||||||
return ( (point[ to ].stones == 1) && (point[ to ].owner == ME) );
|
|
||||||
} /* end: covermine */
|
|
||||||
|
|
||||||
|
|
||||||
idareyou( from, to ) int from, to; {
|
|
||||||
if (unwise( to )) return (FALSE);
|
|
||||||
if ( (point[ from ].stones != 2)
|
|
||||||
&& (point[ to ].stones < 2)
|
|
||||||
&& (scanahead( to ) > 6) ) return ( TRUE );
|
|
||||||
else return (FALSE);
|
|
||||||
} /* end: idareyou */
|
|
||||||
|
|
||||||
|
|
||||||
hitandrun( from, to ) int from, to; {
|
|
||||||
return ( point[ to ].owner == YU );
|
|
||||||
} /* end: hitandrun */
|
|
||||||
|
|
||||||
|
|
||||||
dbuild( from, to ) int from, to; {
|
|
||||||
static int diceleft;
|
|
||||||
diceleft = (myturns? 2 + movesleft: movesleft);
|
|
||||||
if (diceleft > 1) {
|
|
||||||
/* can't possibly be only one stone on from point */
|
|
||||||
/* or kamikaze would have covered it on last move */
|
|
||||||
return ( point[to].stones == 0 );
|
|
||||||
}
|
|
||||||
return (FALSE);
|
|
||||||
} /* end: dbuild */
|
|
||||||
|
|
||||||
|
|
||||||
kamikaze( from, to ) int from, to; {
|
|
||||||
/* cover my distant blot, or razzle-dazzle 'em with the long doubles hit */
|
|
||||||
static int j, k, diceleft;
|
|
||||||
|
|
||||||
k = from;
|
|
||||||
j = from - to;
|
|
||||||
diceleft = myturns * movesleft; /* NB: 2*2 == 2+2, "fourtunately" */
|
|
||||||
while ( diceleft-- ) { /* predicting where doubles land is easy! */
|
|
||||||
k -= j;
|
|
||||||
if (k < 1) return (FALSE); /* out of bounds */
|
|
||||||
if ( point[ k ].stones == 0 ) continue; /* simplify */
|
|
||||||
if ( point[ k ].stones == 1 ) /* found my blot or yours? */
|
|
||||||
return (TRUE);
|
|
||||||
else if ( point[k].owner == YU ) /* found your blockade? */
|
|
||||||
return (FALSE);
|
|
||||||
else continue; /* found my safe point, so ignore it */
|
|
||||||
}
|
|
||||||
return (FALSE);
|
|
||||||
|
|
||||||
} /* end: kamikaze */
|
|
||||||
|
|
||||||
|
|
||||||
hittite( from, to ) int from, to; {
|
|
||||||
return (hitandrun(from,to) && to > 9);
|
|
||||||
} /* end: hittite */
|
|
||||||
|
|
||||||
|
|
||||||
safehit( from, to ) int from, to; {
|
|
||||||
return (hittite(from,to) && idareyou(from,to));
|
|
||||||
} /* end: safehit */
|
|
||||||
|
|
||||||
|
|
||||||
foolsdemise( from, to ) int from, to; {
|
|
||||||
/* annihilate orphaned blots in enemy's inner, my outer table */
|
|
||||||
return (to > 17 && point[to].owner == YU);
|
|
||||||
} /* end: foolsdemise */
|
|
||||||
|
|
||||||
|
|
||||||
landonme( from, to ) int from, to; {
|
|
||||||
if ( plainstupid(from) ) return (FALSE);
|
|
||||||
if ( loneranger(from,to) ) {
|
|
||||||
if (from < 19 && to > 6) return(TRUE);
|
|
||||||
}
|
|
||||||
else return ( point[ to ].owner == ME && point[to].stones < 4);
|
|
||||||
} /* end: landonme */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* these evaluations have meaning only in the endgame */
|
|
||||||
|
|
||||||
|
|
||||||
nobackgammon( from, to ) int from, to; { /* endgame */
|
|
||||||
return (from > 19);
|
|
||||||
} /* end: nobackgammon */
|
|
||||||
|
|
||||||
|
|
||||||
crosstable( from, to ) int from, to; {
|
|
||||||
/* always move a table ahead if possible, in the endgame */
|
|
||||||
if (from < 7) return (FALSE);
|
|
||||||
if (from > 18 && to <= 18) return (TRUE);
|
|
||||||
if (from > 12 && to <= 12) return (TRUE);
|
|
||||||
if (from > 6 && to <= 6) return (TRUE);
|
|
||||||
return (FALSE);
|
|
||||||
} /* end: crosstable */
|
|
||||||
|
|
||||||
|
|
||||||
fiftytworule( from, to ) int from, to; { /* endgame */
|
|
||||||
static int p;
|
|
||||||
if (from < 7) return (FALSE); /* not in inner table! */
|
|
||||||
p = from % 6;
|
|
||||||
if (p == 0) return (TRUE); /* improve the six */
|
|
||||||
if (p != 5) return ( (to % 6) < 3 ); /* best improve under five */
|
|
||||||
} /* end: fiftytworule */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* these evaluations are universally applicable, last resort moves */
|
|
||||||
|
|
||||||
|
|
||||||
gohome( from, to ) int from, to; { /* always go home if you can */
|
|
||||||
return (to == MYHOME);
|
|
||||||
} /* end: gohome */
|
|
||||||
|
|
||||||
|
|
||||||
scatter( from, to ) int from, to; { /* scatter, esp. in the endgame */
|
|
||||||
if (plainstupid(from) || unwise(to)) return (FALSE);
|
|
||||||
return ( point[ from ].stones > 1 && point[ to ].stones == 0 );
|
|
||||||
} /* end: scatter */
|
|
||||||
|
|
||||||
|
|
||||||
runnerup( from, to ) int from, to; {
|
|
||||||
if (from < 10 || from > 18) return (FALSE);
|
|
||||||
return (TRUE);
|
|
||||||
} /* end: runnerup */
|
|
||||||
|
|
||||||
|
|
||||||
loneranger( from, to ) int from, to; {
|
|
||||||
return( point[ from ].stones == 1 );
|
|
||||||
} /* end: loneranger */
|
|
||||||
|
|
||||||
|
|
||||||
run( dummy1, dummy2 ) int dummy1, dummy2; { /* MUST move something! */
|
|
||||||
return (TRUE);
|
|
||||||
} /* end: run */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* clockwise and counterclock make a 1-stone choice on rules of thumb */
|
|
||||||
|
|
||||||
|
|
||||||
counterclock( test ) int (* test)(); {
|
|
||||||
static int i,j;
|
|
||||||
|
|
||||||
for (i = 0; i < 2; i++) {
|
|
||||||
for (j = 1; j < 25; j++) {
|
|
||||||
if ( list[i][j] == ERROR ) continue;
|
|
||||||
if ( (* test)( j, list[i][j] ) ) {
|
|
||||||
lurch( j, list[i][j], i);
|
|
||||||
return ( TRUE );
|
|
||||||
} } }
|
|
||||||
return (FALSE);
|
|
||||||
|
|
||||||
} /* end: counterclock */
|
|
||||||
|
|
||||||
|
|
||||||
clockwise( test ) int (* test)(); {
|
|
||||||
static int i,j;
|
|
||||||
|
|
||||||
for (i = 0; i < 2; i++) {
|
|
||||||
for (j = 25; j > 0; j--) {
|
|
||||||
if ( list[i][j] == ERROR ) continue;
|
|
||||||
if ( (* test)( j, list[i][j] ) ) {
|
|
||||||
lurch( j, list[i][j], i);
|
|
||||||
return ( TRUE );
|
|
||||||
} } }
|
|
||||||
return (FALSE);
|
|
||||||
|
|
||||||
} /* end: clockwise */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*-------------------------------------------*/
|
|
||||||
/* Make Prime */
|
|
||||||
/*-------------------------------------------*/
|
|
||||||
|
|
||||||
static int prmchk;
|
|
||||||
|
|
||||||
|
|
||||||
buildprime( f1,t1,f2,t2 ) int f1,t1,f2,t2; {
|
|
||||||
clrpend();
|
|
||||||
/* check for the doubles bug */
|
|
||||||
if ((dice[0] == dice[1]) && (point[f1].stones < 2)) return(FALSE);
|
|
||||||
|
|
||||||
/* look for the combination */
|
|
||||||
if ( t1 == prmchk && t2 == prmchk) setpend(f2,t2);
|
|
||||||
|
|
||||||
/* stick like glue to a made point, but doubles may move forward */
|
|
||||||
if (dice[0] != dice[1]) {
|
|
||||||
if ((f2 < 8) && (point[f2].stones == 2)) clrpend();
|
|
||||||
if ((f1 < 8) && (point[f1].stones == 2)) clrpend();
|
|
||||||
}
|
|
||||||
|
|
||||||
return(pending.flag);
|
|
||||||
|
|
||||||
} /* end: buildprime */
|
|
||||||
|
|
||||||
|
|
||||||
makeprime() {
|
|
||||||
static int i, tab[] = { ERROR,1,2,3,20,22,24,9,4,6,8,5,7 };
|
|
||||||
i = 12;
|
|
||||||
while (i) {
|
|
||||||
prmchk = tab[i];
|
|
||||||
i--;
|
|
||||||
if ( point[ prmchk ].stones > 1 ) continue;
|
|
||||||
else if ( matchup( buildprime ) ) return(TRUE);
|
|
||||||
}
|
|
||||||
return(FALSE);
|
|
||||||
} /* end: makeprime */
|
|
||||||
|
|
||||||
|
|
||||||
coverprime( from, to ) int from, to; {
|
|
||||||
return (((to == prmchk) &&
|
|
||||||
(point[prmchk].owner == ME)) &&
|
|
||||||
(point[from].stones != 2));
|
|
||||||
} /* coverprime */
|
|
||||||
|
|
||||||
|
|
||||||
cleanup() {
|
|
||||||
static int i, tab[] = { ERROR,1,2,3,20,22,24,9,4,6,8,5,7 };
|
|
||||||
i = 12;
|
|
||||||
while (i) {
|
|
||||||
prmchk = tab[i];
|
|
||||||
i--;
|
|
||||||
if ( point[ prmchk ].stones != 1 ) continue;
|
|
||||||
else if ( counterclock( coverprime ) ) return(TRUE);
|
|
||||||
}
|
|
||||||
return(FALSE);
|
|
||||||
} /* end: cleanup */
|
|
||||||
|
|
||||||
|
|
||||||
/*-------------------------------------*/
|
|
||||||
/* Walking Prime */
|
|
||||||
/*-------------------------------------*/
|
|
||||||
|
|
||||||
swivelhips( from, to ) int from, to; {
|
|
||||||
return ( from > prmchk );
|
|
||||||
} /* end: swivelhips */
|
|
||||||
|
|
||||||
|
|
||||||
slink( from, to ) int from, to; {
|
|
||||||
return( (from > prmchk) && (point[to].stones == 1) );
|
|
||||||
} /* end: slink */
|
|
||||||
|
|
||||||
|
|
||||||
weasel() {
|
|
||||||
if ( clockwise( slink ) )
|
|
||||||
return(TRUE);
|
|
||||||
if ( counterclock( swivelhips ) )
|
|
||||||
return(TRUE);
|
|
||||||
if ( clockwise( run ) )
|
|
||||||
return(TRUE);
|
|
||||||
} /* end: weasel */
|
|
||||||
|
|
||||||
ihaveprime( from ) int from; {
|
|
||||||
static int i, to, ez;
|
|
||||||
ez = 0;
|
|
||||||
for (i = 0; i < 6; i++) {
|
|
||||||
to = from - i;
|
|
||||||
if ((point[to].owner == ME) && (point[to].stones > 1)) ez++;
|
|
||||||
}
|
|
||||||
return (ez > 4);
|
|
||||||
} /* end: ihaveprime */
|
|
||||||
|
|
||||||
|
|
||||||
walkingprime() {
|
|
||||||
/* looks for the walking prime anywhere in the front tables */
|
|
||||||
/* then tries to bring up a runner from behind the prime, */
|
|
||||||
/* ensuring that a back stone WILL move before a front one */
|
|
||||||
static int i;
|
|
||||||
i = 12;
|
|
||||||
while (i > 5) {
|
|
||||||
if ( ihaveprime(i) ) {
|
|
||||||
prmchk = i;
|
|
||||||
if ( weasel() ) return (TRUE);
|
|
||||||
}
|
|
||||||
i--;
|
|
||||||
}
|
|
||||||
return(FALSE);
|
|
||||||
} /* end: walkingprime */
|
|
||||||
|
|
||||||
|
|
||||||
/*---------- Book Moves ----------*/
|
|
||||||
/* only valid if my move is first */
|
|
||||||
/*--------------------------------*/
|
|
||||||
|
|
||||||
zip(a,b,c,d) int a,b,c,d; {
|
|
||||||
lurch(a,b,0);
|
|
||||||
lurch(c,d,0);
|
|
||||||
movesleft = 0; return( TRUE );
|
|
||||||
} /* end: zip */
|
|
||||||
|
|
||||||
|
|
||||||
zoom( a,b,c,d,e,f,g,h ) int a,b,c,d,e,f,g,h; {
|
|
||||||
myturns = 0; zip(a,b,c,d); zip(e,f,g,h); return( TRUE );
|
|
||||||
} /* end: zoom */
|
|
||||||
|
|
||||||
|
|
||||||
book() {
|
|
||||||
int a,b;
|
|
||||||
if (!firstmove) return (FALSE);
|
|
||||||
firstmove = FALSE;
|
|
||||||
a = min(dice[0],dice[1]);
|
|
||||||
b = max(dice[0],dice[1]);
|
|
||||||
switch (level) {
|
|
||||||
case 0: { return ( book0(a,b) ); break; }
|
|
||||||
case 1: { return ( book1(a,b) ); break; }
|
|
||||||
case 2: { return ( book2(a,b) ); break; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
book0( a,b ) int a, b; {
|
|
||||||
switch (a) {
|
|
||||||
case 1: { switch (b) {
|
|
||||||
case 1: return ( zoom(8,7,8,7,6,5,6,5) );
|
|
||||||
case 2: return ( zip(24,23,13,11) );
|
|
||||||
case 3: return ( zip(8,5,6,5) );
|
|
||||||
case 4: return ( zip(24,23,13,9) );
|
|
||||||
case 5: return ( zip(24,23,13,8) );
|
|
||||||
case 6: return ( zip(13,7,8,7) );
|
|
||||||
}
|
|
||||||
break; }
|
|
||||||
case 2: { switch (b) {
|
|
||||||
case 2: return ( zoom(6,4,6,4,13,11,13,11) );
|
|
||||||
case 3: return ( zip(13,11,13,10) );
|
|
||||||
case 4: return ( zip(8,4,6,4) );
|
|
||||||
case 5: return ( zip(13,8,13,11) );
|
|
||||||
case 6: return ( zip(24,18,13,11) );
|
|
||||||
}
|
|
||||||
break; }
|
|
||||||
case 3: { switch (b) {
|
|
||||||
case 3: return ( zoom(13,10,13,10,10,7,10,7) );
|
|
||||||
case 4: return ( zip(13,10,13,9) );
|
|
||||||
case 5: return ( zip(13,10,13,8) );
|
|
||||||
case 6: return ( zip(24,18,13,10) );
|
|
||||||
}
|
|
||||||
break; }
|
|
||||||
case 4: { switch (b) {
|
|
||||||
case 4: return ( zoom(13,9,13,9,24,20,24,20) );
|
|
||||||
case 5: return ( zip(13,8,13,9) );
|
|
||||||
case 6: return ( zip(24,18,18,14) );
|
|
||||||
}
|
|
||||||
break; }
|
|
||||||
case 5: { switch (b) {
|
|
||||||
case 5: return ( zoom(13,8,13,8,8,3,8,3) );
|
|
||||||
case 6: return ( zip(24,18,18,13) );
|
|
||||||
}
|
|
||||||
break; }
|
|
||||||
case 6: { return ( zoom(13,7,13,7,24,18,24,18) );
|
|
||||||
break; }
|
|
||||||
}
|
|
||||||
|
|
||||||
} /* end: book0 */
|
|
||||||
book1( a,b ) int a, b; { /* mostly follows Becker */
|
|
||||||
switch (a) {
|
|
||||||
case 1: { switch (b) {
|
|
||||||
case 1: return ( zoom(8,7,8,7,6,5,6,5) );
|
|
||||||
case 2: return ( zip(13,11,6,5) );
|
|
||||||
case 3: return ( zip(8,5,6,5) );
|
|
||||||
case 4: return ( zip(13,9,6,5) );
|
|
||||||
case 5: return ( zip(13,8,6,5) );
|
|
||||||
case 6: return ( zip(13,7,8,7) );
|
|
||||||
}
|
|
||||||
break; }
|
|
||||||
case 2: { switch (b) {
|
|
||||||
case 2: return ( zoom(6,4,6,4,13,11,13,11) );
|
|
||||||
case 3: return ( zip(13,11,13,10) );
|
|
||||||
case 4: return ( zip(8,4,6,4) );
|
|
||||||
case 5: return ( zip(13,8,13,11) );
|
|
||||||
case 6: return ( zip(13,7,7,5) );
|
|
||||||
}
|
|
||||||
break; }
|
|
||||||
case 3: { switch (b) {
|
|
||||||
case 3: return ( zoom(13,10,13,10,8,5,8,5) );
|
|
||||||
case 4: return ( zip(13,10,13,9) );
|
|
||||||
case 5: return ( zip(13,8,8,5) );
|
|
||||||
case 6: return ( zip(13,7,13,10) );
|
|
||||||
}
|
|
||||||
break; }
|
|
||||||
case 4: { switch (b) {
|
|
||||||
case 4: return ( zoom(13,9,13,9,9,5,9,5) );
|
|
||||||
case 5: return ( zip(13,8,13,9) );
|
|
||||||
case 6: return ( zip(13,7,13,9) );
|
|
||||||
}
|
|
||||||
break; }
|
|
||||||
case 5: { switch (b) {
|
|
||||||
case 5: return ( zoom(13,8,13,8,8,3,8,3) );
|
|
||||||
case 6: return ( zip(13,7,13,8) );
|
|
||||||
}
|
|
||||||
break; }
|
|
||||||
case 6: { return ( zoom(13,7,13,7,24,18,24,18) );
|
|
||||||
break; }
|
|
||||||
}
|
|
||||||
|
|
||||||
} /* end: book1 */
|
|
||||||
book2( a,b ) int a, b; { /* mostly follows Becker */
|
|
||||||
switch (a) {
|
|
||||||
case 1: { switch (b) {
|
|
||||||
case 1: return ( zoom(8,7,8,7,6,5,6,5) );
|
|
||||||
case 2: return ( zip(13,11,24,23) );
|
|
||||||
case 3: return ( zip(8,5,6,5) );
|
|
||||||
case 4: return ( zip(13,9,24,23) );
|
|
||||||
case 5: return ( zip(13,8,24,23) );
|
|
||||||
case 6: return ( zip(13,7,8,7) );
|
|
||||||
}
|
|
||||||
break; }
|
|
||||||
case 2: { switch (b) {
|
|
||||||
case 2: return ( zoom(6,4,6,4,24,23,24,23) );
|
|
||||||
case 3: return ( zip(13,11,13,10) );
|
|
||||||
case 4: return ( zip(8,4,6,4) );
|
|
||||||
case 5: return ( zip(13,8,13,11) );
|
|
||||||
case 6: return ( zip(13,7,13,11) );
|
|
||||||
}
|
|
||||||
break; }
|
|
||||||
case 3: { switch (b) {
|
|
||||||
case 3: return ( zoom(13,10,13,10,10,7,10,7) );
|
|
||||||
case 4: return ( zip(13,10,13,9) );
|
|
||||||
case 5: return ( zip(13,8,8,5) );
|
|
||||||
case 6: return ( zip(13,7,13,10) );
|
|
||||||
}
|
|
||||||
break; }
|
|
||||||
case 4: { switch (b) {
|
|
||||||
case 4: return ( zoom(13,9,13,9,9,5,9,5) );
|
|
||||||
case 5: return ( zip(13,8,13,9) );
|
|
||||||
case 6: return ( zip(13,7,13,9) );
|
|
||||||
}
|
|
||||||
break; }
|
|
||||||
case 5: { switch (b) {
|
|
||||||
case 5: return ( zoom(13,8,13,8,8,3,8,3) );
|
|
||||||
case 6: return ( zip(13,7,13,8) );
|
|
||||||
}
|
|
||||||
break; }
|
|
||||||
case 6: { return ( zoom(13,7,13,7,24,18,24,18) );
|
|
||||||
break; }
|
|
||||||
}
|
|
||||||
|
|
||||||
} /* end: book2 */
|
|
||||||
|
|
||||||
|
|
||||||
/*====== MyMove ======*/
|
|
||||||
|
|
||||||
torve() {
|
|
||||||
if ( makeprime() ) { /* this will use doubles, if it can */
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if ( walkingprime() ) { /* i have six prime points, so run!!! */
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if ( dice[0] == dice[1] ) { /* this is too easy! */
|
|
||||||
if ( counterclock( kamikaze ) )
|
|
||||||
return;
|
|
||||||
if ( counterclock( dbuild ) ) /* claim new turf */
|
|
||||||
return;
|
|
||||||
if ( clockwise( run ) )
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if ( cleanup() ) { /* cover my single blot on prime points */
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if ( bearoff() ) { /* I'm ready, but you're in the back game! */
|
|
||||||
if ( counterclock( gohome ) )
|
|
||||||
return;
|
|
||||||
if ( clockwise( run ) )
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if ( clockwise( hitandrun ) )
|
|
||||||
return;
|
|
||||||
if ( matchup( natural ) )
|
|
||||||
return;
|
|
||||||
if ( clockwise( landonme ) )
|
|
||||||
return;
|
|
||||||
if ( counterclock( runnerup ) )
|
|
||||||
return;
|
|
||||||
if ( clockwise( scatter ) )
|
|
||||||
return;
|
|
||||||
if ( clockwise( run ) )
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
} /* end: torve */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
villiers() {
|
|
||||||
if ( makeprime() ) { /* this will use doubles, if it can */
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if ( walkingprime() ) { /* i have six prime points, so run!!! */
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if ( dice[0] == dice[1] ) { /* this is too easy! */
|
|
||||||
if ( counterclock( kamikaze ) )
|
|
||||||
return;
|
|
||||||
if ( counterclock( dbuild ) ) /* claim new turf */
|
|
||||||
return;
|
|
||||||
if ( clockwise( run ) )
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if ( cleanup() ) { /* cover my single blot on prime points */
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if ( bearoff() ) { /* I'm ready, but you're in the back game! */
|
|
||||||
if ( counterclock( gohome ) )
|
|
||||||
return;
|
|
||||||
if ( clockwise( run ) )
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if ( clockwise( foolsdemise ) )
|
|
||||||
return;
|
|
||||||
if ( clockwise( idareyou ) )
|
|
||||||
return;
|
|
||||||
if ( counterclock( covermine ) )
|
|
||||||
return;
|
|
||||||
if ( matchup( natural ) )
|
|
||||||
return;
|
|
||||||
if ( clockwise( landonme ) )
|
|
||||||
return;
|
|
||||||
if ( clockwise( runnerup ) )
|
|
||||||
return;
|
|
||||||
if ( clockwise( scatter ) )
|
|
||||||
return;
|
|
||||||
if ( clockwise( run ) )
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
} /* end: villiers */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
louisa() {
|
|
||||||
if ( makeprime() ) { /* this will use doubles, if it can */
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if ( walkingprime() ) { /* i have six prime points, so run!!! */
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if ( dice[0] == dice[1] ) { /* this is too easy! */
|
|
||||||
if ( counterclock( kamikaze ) )
|
|
||||||
return;
|
|
||||||
if ( counterclock( dbuild ) ) /* claim new turf */
|
|
||||||
return;
|
|
||||||
if ( clockwise( run ) )
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if ( cleanup() ) { /* cover my single blot on prime points */
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if ( bearoff() ) { /* I'm ready, but you're in the back game! */
|
|
||||||
if ( counterclock( gohome ) )
|
|
||||||
return;
|
|
||||||
if ( clockwise( run ) )
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if ( (!naked() && goodboard()) || yourfolly() ) {
|
|
||||||
if ( clockwise( hitandrun ) )
|
|
||||||
return;
|
|
||||||
if ( matchup( natural ) )
|
|
||||||
return;
|
|
||||||
if ( clockwise( landonme ) )
|
|
||||||
return;
|
|
||||||
if ( counterclock( runnerup ) )
|
|
||||||
return;
|
|
||||||
if ( clockwise( scatter ) )
|
|
||||||
return;
|
|
||||||
if ( clockwise( run ) )
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if ( clockwise( foolsdemise ) )
|
|
||||||
return;
|
|
||||||
if ( clockwise( idareyou ) )
|
|
||||||
return;
|
|
||||||
if ( counterclock( covermine ) )
|
|
||||||
return;
|
|
||||||
if ( matchup( natural ) )
|
|
||||||
return;
|
|
||||||
if ( clockwise( landonme ) )
|
|
||||||
return;
|
|
||||||
if ( clockwise( runnerup ) )
|
|
||||||
return;
|
|
||||||
if ( clockwise( scatter ) )
|
|
||||||
return;
|
|
||||||
if ( clockwise( run ) )
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} /* end: louisa */
|
|
||||||
|
|
||||||
|
|
||||||
mymove() {
|
|
||||||
int i, d;
|
|
||||||
|
|
||||||
if ( nomove() ) {
|
|
||||||
if (lookforit && (dice[0] != dice[1])) {
|
|
||||||
lookforit = FALSE;
|
|
||||||
puts("\008... ");
|
|
||||||
switch (level) {
|
|
||||||
case 0: { puts("Blocked!"); break; }
|
|
||||||
case 1: { puts("Well, no!"); break; }
|
|
||||||
case 2: { puts("Thurb!"); break; }
|
|
||||||
}
|
|
||||||
sleep(10);
|
|
||||||
restoreboard();
|
|
||||||
update();
|
|
||||||
|
|
||||||
/* put the high die in list zero */
|
|
||||||
d = dice[0]; dice[0] = dice[1]; dice[1] = d;
|
|
||||||
|
|
||||||
cantuse = ERROR; movesleft = 2; myturns = 1;
|
|
||||||
switch (level) {
|
|
||||||
case 0: { setchat("I move"); break; }
|
|
||||||
case 1: { setchat("Let's try"); break; }
|
|
||||||
case 2: { setchat("Move is"); break; }
|
|
||||||
}
|
|
||||||
debug(chatter);
|
|
||||||
prmchk = 12;
|
|
||||||
weasel();
|
|
||||||
/* the rules say, use both dice if you can, or */
|
|
||||||
/* the highest if one or the other but not both */
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
lookforit = TRUE;
|
|
||||||
strcat(chatter," and now I'm blocked ");
|
|
||||||
myturns = movesleft = 0;
|
|
||||||
} }
|
|
||||||
else if ( book() ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if ( pending.flag ) {
|
|
||||||
lurch( pending.fr, pending.to, 1 );
|
|
||||||
clrpend();
|
|
||||||
}
|
|
||||||
else if ( endgame() ) { /* very solid tactics here!! */
|
|
||||||
if ( clockwise( gohome ) )
|
|
||||||
return;
|
|
||||||
if ( clockwise( nobackgammon ) ) /* no excuse! */
|
|
||||||
return;
|
|
||||||
if ( clockwise( crosstable ) )
|
|
||||||
return;
|
|
||||||
if ( clockwise( fiftytworule ) )
|
|
||||||
return;
|
|
||||||
if ( clockwise( scatter ) )
|
|
||||||
return;
|
|
||||||
if ( clockwise( run ) )
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if ( point[ MYBAR ].stones > 0 ) { /* I'm on the bar! */
|
|
||||||
if ( clockwise( hitandrun ) ) /* wreak havoc, please */
|
|
||||||
return;
|
|
||||||
if ( clockwise( run ) ) /* note: uses low die first */
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else switch (level) {
|
|
||||||
case 0: { villiers(); break; }
|
|
||||||
case 1: { louisa(); break; }
|
|
||||||
case 2: { torve(); break; }
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} /* end: mymove */
|
|
||||||
|
|
||||||
/*------------------------------*/
|
|
||||||
/* end of the GAMEPLAN.C module */
|
|
||||||
/*------------------------------*/
|
|
||||||
|
|
42
gameplan.hdr
42
gameplan.hdr
@ -1,42 +0,0 @@
|
|||||||
/* GAMEPLAN.HDR */
|
|
||||||
|
|
||||||
/*================================================================*/
|
|
||||||
/* change nothing in this file */
|
|
||||||
/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
|
|
||||||
|
|
||||||
#define TRUE 1
|
|
||||||
#define FALSE 0
|
|
||||||
#define ME 1
|
|
||||||
#define YU 2
|
|
||||||
#define YRBAR 0
|
|
||||||
#define MYBAR 25
|
|
||||||
#define YRHOME 26
|
|
||||||
#define MYHOME 27
|
|
||||||
#define ERROR 999
|
|
||||||
#define MYLEVEL 2
|
|
||||||
|
|
||||||
extern int list[2][28]; /* two dice, two lists */
|
|
||||||
|
|
||||||
extern struct board {
|
|
||||||
int stones, /* number of stones on that point */
|
|
||||||
owner, /* and whose they are */
|
|
||||||
x,y, /* x and y coordinates of point base */
|
|
||||||
lastx,lasty, /* last location drawn on this point */
|
|
||||||
cx,cy; /* coordinates for column numbers */
|
|
||||||
}
|
|
||||||
point[28], bdsave[28]; /* 24 points, plus 2 bars, 2 homes */
|
|
||||||
|
|
||||||
extern struct { int cube, whosecube; } doubles;
|
|
||||||
|
|
||||||
extern struct { int fr,to,flag; } pending;
|
|
||||||
|
|
||||||
extern int level, dice[2], myscore, yrscore, player, movesleft, cantuse,
|
|
||||||
myturns, swapped, tswap, deciding, expert, tone, show, moremsgline,
|
|
||||||
firstmove, helpdisabled, yrdice, lookforit, startcubevalue;
|
|
||||||
|
|
||||||
extern char *chatter[80];
|
|
||||||
|
|
||||||
/*----------------------------------------------*/
|
|
||||||
/* end of header -- change NOTHING in this file */
|
|
||||||
/*----------------------------------------------*/
|
|
||||||
|
|
541
mylib2.c
541
mylib2.c
@ -1,541 +0,0 @@
|
|||||||
/*
|
|
||||||
MYLIB2.C
|
|
||||||
|
|
||||||
These routines are CONDITIONALLY compiled; i.e., only as needed.
|
|
||||||
|
|
||||||
----------------------------------------------------------------------
|
|
||||||
Incorporates special mods used by my Backgammon game, BACKGMMN.C etc.
|
|
||||||
----------------------------------------------------------------------
|
|
||||||
|
|
||||||
A set of common I/O functions that seem to turn up a lot in my programs,
|
|
||||||
including terminal functions for Kaypro 10, 4'84, 2X etc.
|
|
||||||
|
|
||||||
Uses Software Toolworks' C/80 3.1 compiler. Place #include "mylib2.c" at the
|
|
||||||
end of your source file for correct CONDITIONAL COMPILATION.
|
|
||||||
|
|
||||||
David C. Oshel
|
|
||||||
1219 Harding Ave.
|
|
||||||
Ames, Iowa 50010
|
|
||||||
|
|
||||||
Last modified: March 25, 1986
|
|
||||||
|
|
||||||
-----------------------------------------------------------------------------
|
|
||||||
** WARNING ** These routines use direct console IO, bdos function 6!
|
|
||||||
|
|
||||||
YOU MUST CALL INIT_LIB() BEFORE USING THESE ROUTINES!
|
|
||||||
|
|
||||||
======= UTILITIES =======
|
|
||||||
|
|
||||||
* init_lib() - CALL THIS FIRST, OR THE RESULT WILL BE VERY STRANGE!
|
|
||||||
*
|
|
||||||
* puts(p) - unformatted print, e.g., puts("Hello, sailor!\n");
|
|
||||||
* gets(p,max) - printable input only, no prompt character
|
|
||||||
*
|
|
||||||
* ask(p) - demand Yes or No response to question p
|
|
||||||
* random() - effective random 16-bit integer IFF gets() is used
|
|
||||||
* sleep(n) - sleep n/10ths of a second, roughly (from C80.LIB)
|
|
||||||
* rollup() - roll up 23 lines of screen
|
|
||||||
* ONscript() - printer echo ON for output via puts, chrout
|
|
||||||
* OFFscript() - printer echo OFF for output via puts, chrout
|
|
||||||
* ONinterrupt() - Ctl-C, Ctl-B cause program exit
|
|
||||||
* OFFinterrupt() - Ctl-C, Ctl-B cause comedy
|
|
||||||
* hide_input(p,max) - like gets, but used when entering passwords
|
|
||||||
* chrout(c) - if scripting, echo output also to LST:
|
|
||||||
* putscreen(p) - like puts, but always and only to screen
|
|
||||||
|
|
||||||
|
|
||||||
======= KAYPRO 10 TERMINAL/VIDEO FUNCTIONS =======
|
|
||||||
|
|
||||||
* gotoxy(x,y) - 0,0 is top left, horz <= 79 precedes vert <= 24,
|
|
||||||
* where 0,24 is on the 25th, status, line.
|
|
||||||
* beep() - terminal bell
|
|
||||||
* home() - home cursor, do not clear screen
|
|
||||||
* clr_screen() - home and clear
|
|
||||||
*
|
|
||||||
* shadow_box(h,v,x1,y1,x2,y2) - like box, but with shadow, calls box
|
|
||||||
* box(tlx,tly,brx,bry) - draw a line box, coords: topleft XY, bottomright XY
|
|
||||||
* note that box calls ldraw(x1,y1,x2,y2), below
|
|
||||||
*
|
|
||||||
* clr_lend() - clear from cursor to end of line
|
|
||||||
* clr_send() - clear from cursor to end of screen
|
|
||||||
* rev_vid(),
|
|
||||||
* nor_vid() - reverse field
|
|
||||||
* dim_vid(),
|
|
||||||
* bri_vid() - low/high intensity
|
|
||||||
* on_blink(),
|
|
||||||
* off_blink() - blinking chars
|
|
||||||
* ul_start(),
|
|
||||||
* ul_stop() - start/stop underline
|
|
||||||
* save_cursor(),
|
|
||||||
* retn_cursor() - remember/restore current cursor location
|
|
||||||
* ins_line(),
|
|
||||||
* del_line() - insert/delete screen text line
|
|
||||||
* on_cursor(),
|
|
||||||
* off_cursor() - hide/show cursor
|
|
||||||
* vm_on(),
|
|
||||||
* vm_off() - "Video Mode" commands
|
|
||||||
* pixel(x,y) - draw pixel at x,y (video coords, x <= 159, y <= 99)
|
|
||||||
* no_pixel(x,y) - erase pixel at x,y
|
|
||||||
* ldraw(x1,y1,x2,y2) - draw/ erase graphics line, see discussion for box
|
|
||||||
* lwipe(x1,y1,x2,y2) - range for video coordinates as for pixel
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef TRUE
|
|
||||||
#define TRUE 1
|
|
||||||
#endif
|
|
||||||
#ifndef FALSE
|
|
||||||
#define FALSE 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* hide this here so's not to worry about it elsewhere */
|
|
||||||
/* "printf.c" collides with one of these, can't remember which */
|
|
||||||
/* puts() takes longer to write, but executes faster */
|
|
||||||
extern char Cmode, IOpread[4], IOpwrit[4], IOpeof[4];
|
|
||||||
|
|
||||||
/* make these known only to what follows */
|
|
||||||
static int MYbstout, MYscrtp, MYretnirp; /* odd names mark semi-private */
|
|
||||||
static unsigned RNDloc; /* effective random location, bumped by gets() */
|
|
||||||
/* and scrambled when the LCG random() is called */
|
|
||||||
/* makes a decent algorithm for interactive games */
|
|
||||||
|
|
||||||
|
|
||||||
#ifneed init_lib
|
|
||||||
init_lib() {
|
|
||||||
|
|
||||||
MYretnirp = fopen("LST:","w");
|
|
||||||
OFFscript();
|
|
||||||
ONinterrupt();
|
|
||||||
Cmode = 0;
|
|
||||||
IOpread[0] = 6; IOpwrit[0] = 6;
|
|
||||||
|
|
||||||
} /* end: init_lib */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifneed random
|
|
||||||
random() { /* depends on effective random location spun by gets() */
|
|
||||||
|
|
||||||
RNDloc = 2053 * RNDloc + 13849;
|
|
||||||
return (RNDloc);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifneed ONscript
|
|
||||||
ONscript() {
|
|
||||||
|
|
||||||
MYscrtp = TRUE;
|
|
||||||
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifneed OFFscript
|
|
||||||
OFFscript() {
|
|
||||||
|
|
||||||
MYscrtp = FALSE;
|
|
||||||
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifneed ONinterrupt
|
|
||||||
ONinterrupt() {
|
|
||||||
|
|
||||||
MYbstout = TRUE;
|
|
||||||
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifneed OFFinterrupt
|
|
||||||
OFFinterrupt() {
|
|
||||||
|
|
||||||
MYbstout = FALSE;
|
|
||||||
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifneed ask
|
|
||||||
ask(p) char *p; {
|
|
||||||
|
|
||||||
char ch, resp[2];
|
|
||||||
|
|
||||||
loo: puts(p);
|
|
||||||
gets(resp,1);
|
|
||||||
ch = toupper( *resp );
|
|
||||||
if ( !( ch == 'Y' || ch == 'N' )) {
|
|
||||||
puts("Please answer the question, Yes or No.\n");
|
|
||||||
goto loo;
|
|
||||||
}
|
|
||||||
return (ch == 'Y');
|
|
||||||
|
|
||||||
} /* end: ask */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifneed rollup
|
|
||||||
rollup() {
|
|
||||||
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i=0; i<23; i++) puts("\n");
|
|
||||||
|
|
||||||
} /* end: rollup */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifneed sleep
|
|
||||||
sleep( n ) int n; { /* sleep for n/10 seconds, 0 <= n < 256 */
|
|
||||||
|
|
||||||
n; /* get n into HL */
|
|
||||||
#asm
|
|
||||||
MOV B,L ;delay B/10ths of a second
|
|
||||||
__DL0: MVI A,100 ;100 milliseconds, 1/10 second
|
|
||||||
__DL1: MVI C,249 ;1 millisecond per unit of A at 4 MHz
|
|
||||||
__DL2: DCR C ;Leventhal, Z80 Assembly Language Programming
|
|
||||||
JNZ __DL2
|
|
||||||
DCR A
|
|
||||||
JNZ __DL1
|
|
||||||
DCR B
|
|
||||||
JNZ __DL0 ;on exit, HL has FALSE if n was 0, else TRUE
|
|
||||||
#endasm
|
|
||||||
} /* end: sleep */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/*========================================*/
|
|
||||||
/* GETS(p, maxinput) */
|
|
||||||
/* Local getline function with special *---* WARNING: */
|
|
||||||
/* input handling, 1 <= len <= maxinput *---* Execute INIT_LIB() first !! */
|
|
||||||
/* Updates effective random, RNDloc, */
|
|
||||||
/* Forces input from CONSOLE only! */
|
|
||||||
/*========================================*/
|
|
||||||
|
|
||||||
#ifneed gets
|
|
||||||
gets(p,maxinput) char *p; int maxinput; {
|
|
||||||
|
|
||||||
/* This function depends on BDOS Function #6. Init_lib() sets Cmode=0 and
|
|
||||||
IOpread[0]=6 and IOpwrit[0]=6 (courtesy of and peculiar to C/80 3.1)
|
|
||||||
YOU must ensure that the target string is long enough to collect the
|
|
||||||
entire maximum input allowed and specified, INCLUDING FINAL NULL! */
|
|
||||||
|
|
||||||
static int len;
|
|
||||||
static char ch;
|
|
||||||
|
|
||||||
len = -1;
|
|
||||||
if (maxinput < 1 || maxinput > 127) maxinput = 79;
|
|
||||||
|
|
||||||
/*--------------------------------*/
|
|
||||||
/* SPECIAL ROUTINE FOR BACKGAMMON */
|
|
||||||
/*--------------------------------*/
|
|
||||||
|
|
||||||
loo: while ( !(ch = getc(0)) ) acg(); /* keep the game lively */
|
|
||||||
|
|
||||||
if (len < 0) len = 0; /* don't destroy prompt by backing up */
|
|
||||||
if (ch == '\n') { /* end of line? don't store newline */
|
|
||||||
*p = '\0'; /* mark it with a B for baby and me */
|
|
||||||
/* chrout('\n'); */ /* but DON'T echo newline */
|
|
||||||
return ( len ); /* <--- HERE IS THE FUNCTION EXIT! */
|
|
||||||
}
|
|
||||||
else if (ch == '\b' || ch == 0x7F) { /* backspace? rubout? */
|
|
||||||
if (len--) { /* where's the prompt? */
|
|
||||||
puts("\008 \008"); /* we're ok, echo erase */
|
|
||||||
p--; /* delete from string */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*--------------------------------*/
|
|
||||||
/* SPECIAL ROUTINE FOR BACKGAMMON */
|
|
||||||
/*--------------------------------*/
|
|
||||||
|
|
||||||
else if (ch == '\003') { /* user bailout key is Ctrl-C, not ESC */
|
|
||||||
if (MYbstout) exit();
|
|
||||||
else {
|
|
||||||
haltgame(); /* sets whofirst flag and does jumpjack() */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (ch == '\025' || ch == '\030') { /* Ctl-U, Ctl-X */
|
|
||||||
while (len--) {
|
|
||||||
p--;
|
|
||||||
puts("\008 \008");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (len == maxinput) { /* test specials before testing len */
|
|
||||||
chrout('\007');
|
|
||||||
}
|
|
||||||
else if (ch > 31 && ch < 127) { /* printable char? */
|
|
||||||
chrout(ch); /* yes, echo it */
|
|
||||||
*p++ = ch; /* collect it */
|
|
||||||
len++; /* keep track of it */
|
|
||||||
}
|
|
||||||
else { /* control chars? */
|
|
||||||
chrout('\007');
|
|
||||||
}
|
|
||||||
goto loo;
|
|
||||||
|
|
||||||
} /* end: gets */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifneed hide_input
|
|
||||||
hide_input(s,len) char *s; int len; {
|
|
||||||
|
|
||||||
/* receive at most len chars in s buffer,
|
|
||||||
terminate string with zero,
|
|
||||||
but echo each char with 1, 2, or 3 meaningless dots */
|
|
||||||
|
|
||||||
char ch; int num;
|
|
||||||
|
|
||||||
if ((len < 1) || (len > 127)) len = 127;
|
|
||||||
num = 0;
|
|
||||||
for (;;) { /* forever */
|
|
||||||
while ((ch = getc(0)) == 0) /* bdos 6 does not wait, so we do */
|
|
||||||
;
|
|
||||||
if ((ch == '\r') || (ch == '\n') || (num++ > len)) {
|
|
||||||
/* not sure what the CR key actually is to bdos 6 & C/80 */
|
|
||||||
*s++ = '\0';
|
|
||||||
return; /* this way out */
|
|
||||||
}
|
|
||||||
if ((num % 2) == 0) putc('.',0); /* deception, illusion */
|
|
||||||
if ((num % 5) == 0) putc('.',0);
|
|
||||||
putc('.',0);
|
|
||||||
*s++ = ch;
|
|
||||||
}
|
|
||||||
|
|
||||||
} /* end: hide_input */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------ kpro stuff -------------------------*/
|
|
||||||
|
|
||||||
#ifneed shadow_box
|
|
||||||
/* like box, but with horizontal & vertical displacement for shadow */
|
|
||||||
shadow_box(h,v,x1,y1,x2,y2) int h,v,x1,y1,x2,y2;
|
|
||||||
{
|
|
||||||
box(x1+h,y1+v,x2+h,y2+v); /* draw the shadow */
|
|
||||||
box(x1,y1,x2,y2); /* draw the box */
|
|
||||||
ldraw(x1+h,y1+v,x1,y1); /* draw the corners */
|
|
||||||
ldraw(x2+h,y2+v,x2,y2);
|
|
||||||
ldraw(x2+h,y1+v,x2,y1);
|
|
||||||
ldraw(x1+h,y2+v,x1,y2);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifneed box
|
|
||||||
/* parameters are topleft X,Y and bottomright X,Y
|
|
||||||
X ranges from 0 to 159, Y ranges from 0 to 99, top left is 0,0
|
|
||||||
*/
|
|
||||||
box(x1,y1,x2,y2) int x1,y1,x2,y2; {
|
|
||||||
ldraw(x1,y1,x1,y2);
|
|
||||||
ldraw(x1,y2,x2,y2); /* appears to draw the box anticlockwise */
|
|
||||||
ldraw(x2,y1,x2,y2);
|
|
||||||
ldraw(x1,y1,x2,y1);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifneed gotoxy
|
|
||||||
gotoxy (xpos,ypos) int xpos,ypos; { /* 0,0 is top left corner */
|
|
||||||
putscreen("\033=");
|
|
||||||
putc(ypos+' ',0);
|
|
||||||
putc(xpos+' ',0);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifneed beep
|
|
||||||
beep() { putc(7,0); } /* send bell character */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifneed home
|
|
||||||
home() { putc(30,0); } /* home cursor to top left */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifneed clr_screen
|
|
||||||
clr_screen() { putc(26,0); } /* home and erase screen */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifneed clr_lend
|
|
||||||
clr_lend() { putc(24,0); } /* clear to end of line */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifneed clr_send
|
|
||||||
clr_send() { putc(23,0); } /* clear to end of screen */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifneed rev_vid
|
|
||||||
rev_vid() { putscreen ("\033B0"); } /* reverse background */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifneed nor_vid
|
|
||||||
nor_vid() { putscreen ("\033C0"); }
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifneed dim_vid
|
|
||||||
dim_vid() { putscreen ("\033B1"); } /* low intensity */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifneed bri_vid
|
|
||||||
bri_vid() { putscreen ("\033C1"); }
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifneed on_blink
|
|
||||||
on_blink() { putscreen ("\033B2"); } /* blinking characters */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifneed off_blink
|
|
||||||
off_blink() { putscreen ("\033C2"); }
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifneed ul_start
|
|
||||||
ul_start() { putscreen ("\033B3"); } /* underline */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifneed ul_stop
|
|
||||||
ul_stop() { putscreen ("\033C3"); }
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifneed save_cursor
|
|
||||||
save_cursor() { putscreen ("\033B6"); } /* remember cursor position */
|
|
||||||
#endif
|
|
||||||
#ifneed retn_cursor
|
|
||||||
retn_cursor() { putscreen ("\033C6"); } /* return to remembered pos */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifneed on_status
|
|
||||||
on_status() { putscreen ("\033B7"); } /* status line preservation on */
|
|
||||||
#endif
|
|
||||||
#ifneed off_status
|
|
||||||
off_status() { putscreen ("\033C7"); }
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifneed ins_line
|
|
||||||
ins_line() { /* insert text line */
|
|
||||||
putscreen("\033R");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifneed del_line
|
|
||||||
del_line() { /* delete text line */
|
|
||||||
putscreen("\033E");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifneed on_cursor
|
|
||||||
on_cursor() { putscreen ("\033B4"); } /* (in)visible cursor */
|
|
||||||
#endif
|
|
||||||
#ifneed off_cursor
|
|
||||||
off_cursor() { putscreen ("\033C4"); }
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Video Mode ON/OFF: video WORD, 8 bit video if 15 and 7 are both high */
|
|
||||||
/* VM-ON 10000001 11111111 VM-OFF */
|
|
||||||
/* ^video ^x^video */
|
|
||||||
/* otherwise, video BYTE, high bit 7 interprets bits 0-6 as screen dots */
|
|
||||||
/* 11111111 */
|
|
||||||
/* ^video */
|
|
||||||
/* e.g., */
|
|
||||||
/* Non-VideoMode VideoMode */
|
|
||||||
/* xx 1 11:0 where % is 1 01:0 1 11:0 xx */
|
|
||||||
/* xx 3 11 2 the video 3 00 2 3 11 2 xx */
|
|
||||||
/* xx 5 11 4 flag bit, 5 00 4 5 11 4 xx */
|
|
||||||
/* x 7:%1 6 x is pixel 7:%0 6 7:%1 6 xx */
|
|
||||||
/* ^ ^ ^ */
|
|
||||||
/* to set the pixels, first do a gotoxy to character screen position */
|
|
||||||
/* this mode is faster than Pixel ON/OFF if values are drawn from table */
|
|
||||||
#ifneed vm_on
|
|
||||||
vm_on() { putscreen ("\033B5"); } /* video mode on */
|
|
||||||
#endif
|
|
||||||
#ifneed vm_off
|
|
||||||
vm_off() { putscreen ("\033C5"); }
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifneed pixel
|
|
||||||
pixel(x,y) int x,y; { /* x <= 159, y <= 99 */
|
|
||||||
putscreen("\033*");
|
|
||||||
putc(y+' ',0); putc(x+' ',0);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifneed no_pixel
|
|
||||||
no_pixel(x,y) int x,y; { /* x <= 159, y <= 99 */
|
|
||||||
putscreen("\033 ");
|
|
||||||
putc(y+' ',0); putc(x+' ',0);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifneed ldraw
|
|
||||||
/* use x1 <= x2, y1 <= y2, order is significant (Kaypro bug?) */
|
|
||||||
ldraw(x1,y1,x2,y2) int x1,x2,y1,y2; { /* x <= 159, y <= 99 */
|
|
||||||
putscreen("\033L");
|
|
||||||
putc(y1+' ',0); putc(x1+' ',0);
|
|
||||||
putc(y2+' ',0); putc(x2+' ',0);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifneed lwipe
|
|
||||||
lwipe(x1,y1,x2,y2) int x1,x2,y1,y2; { /* x <= 159, y <= 99 */
|
|
||||||
putscreen("\033D");
|
|
||||||
putc(y1+' ',0); putc(x1+' ',0);
|
|
||||||
putc(y2+' ',0); putc(x2+' ',0);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifneed putscreen
|
|
||||||
putscreen(p) char *p; {
|
|
||||||
|
|
||||||
while (*p) putc(*p++,0);
|
|
||||||
|
|
||||||
} /* end: putscreen */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifneed puts
|
|
||||||
puts(p) char *p; {
|
|
||||||
|
|
||||||
while (*p) chrout(*p++);
|
|
||||||
|
|
||||||
} /* end: puts */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifneed chrout
|
|
||||||
chrout(c) char c; { /* SPECIAL FOR SCRIPT OPTION WITH LST: */
|
|
||||||
|
|
||||||
putc(c,0);
|
|
||||||
if ( MYscrtp ) putc(c,MYretnirp);
|
|
||||||
|
|
||||||
} /* end: chrout */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* end: MYLIB.C */
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user