[alt.sources] UnixChess01/10

ml@brumuc.muc.sub.org (Marc Laukien) (05/20/91)

Submitted-by: ml@brumuc.muc.sub.org
Archive-name: UnixChess/part01

This is UnixChess V2.7, a chess program designed for bulletin board
systems. It's tested with Interactive Unix 2.2.

The program has the following features:

o	Large opening library
o	Training mode with variable levels, 'take back', setup etc.
o	Tournament mode versus the computer
o	Tournament mode versus other players
o	Highscoretable for the tournament games

Unfortunately, I've only provided a german manual. It would be
great, if someone who speaks english and german well, could translate
and post it. However, the program itself, as well as the installation
instructions, are provided in english and german.

If you have any problems to install it, write an email to
'ml@brumuc.muc.sub.org'.

---- Cut Here and feed the following to sh ----
#!/bin/sh
# This is UnixChess, a shell archive (produced by shar 3.49)
# To extract the files from this archive, save it to a file, remove
# everything above the "!/bin/sh" line above, and type "sh file_name".
#
# made 05/20/1991 00:05 UTC by ml@brumuc.muc.sub.org
# Source directory /usr2/games/xchess/XChess_V2.7
#
# existing files will NOT be overwritten unless -c is specified
#
# This is part 1 of a multipart archive                                    
# do not concatenate these parts, unpack them in order with /bin/sh        
#
# This shar contains:
# length  mode       name
# ------ ---------- ------------------------------------------
#    808 -rw-r--r-- README.eng
#    651 -rw-r--r-- README.ger
#   5280 -rw-r--r-- ch/value.c
#   7880 -rw-r--r-- ch/main.c
#   4354 -rw-r--r-- ch/move.c
#   7250 -rw-r--r-- ch/comp.c
#   7922 -rw-r--r-- ch/utility.c
#   3106 -rw-r--r-- ch/threat.c
#   4881 -rw-r--r-- ch/init.c
#   7783 -rw-r--r-- ch/list.c
#   5629 -rw-r--r-- ch/archiv.c
#   7762 -rw-r--r-- ch/open.c
#   2027 -rw-r--r-- ch/stat.c
#   3355 -rw-r--r-- ad/main.c
#   4435 -rw-r--r-- ad/init.c
#   4819 -rw-r--r-- ad/utility.c
#    752 -rw-r--r-- ad/monitor.c
#   6749 -rw-r--r-- ad/window.c
#   3257 -rw-r--r-- ad/move.c
#   2103 -rw-r--r-- ad/interrupt.c
#   2094 -rw-r--r-- ad/load.c
#   3404 -rw-r--r-- ad/menu.c
#   2071 -rw-r--r-- ad/lock.c
#   7463 -rw-r--r-- ad/admin.c
#   5856 -rw-r--r-- ad/screen.c
#   1569 -rw-r--r-- ad/id.c
#   5003 -rw-r--r-- ad/score.c
#   2942 -rw-r--r-- ad/training.c
#   4036 -rw-r--r-- ad/tour_user.c
#   3534 -rw-r--r-- ad/tour_comp.c
#   4458 -rw-r--r-- ad/expire.c
#   3935 -rw-r--r-- ad/setup.c
#   1141 -rw-r--r-- br/break.c
#   6012 -rw-r--r-- ad/ad.h
#   6139 -rw-r--r-- ch/ch.h
#    557 -rw-r--r-- ch/ph.h
#    277 -rw-r--r-- ad/patchlevel.h
#   4484 -rw-r--r-- ad/lex.l
#    277 -rw-r--r-- ad/patchlevel.h
#    636 -rw-r--r-- op/op.albinsgegam
#  24557 -rw-r--r-- op/op.aljechin
#    880 -rw-r--r-- op/op.b2b4
#  13307 -rw-r--r-- op/op.benoni
#    687 -rw-r--r-- op/op.bird
#    559 -rw-r--r-- op/op.budapestgam
#   2227 -rw-r--r-- op/op.caro-kann
#    659 -rw-r--r-- op/op.damenbaspie
#   2491 -rw-r--r-- op/op.damengam
#   1445 -rw-r--r-- op/op.damenind
#    582 -rw-r--r-- op/op.dreispring
#  35579 -rw-r--r-- op/op.englisch
#    887 -rw-r--r-- op/op.evansgam
#  24668 -rw-r--r-- op/op.franz
#  23156 -rw-r--r-- op/op.gruenfeld
#    666 -rw-r--r-- op/op.holland
#    533 -rw-r--r-- op/op.indisch
#   4496 -rw-r--r-- op/op.italienisch
#    596 -rw-r--r-- op/op.katalanisch
#   9399 -rw-r--r-- op/op.koenigsgam
#   1618 -rw-r--r-- op/op.koenigsind
#   1386 -rw-r--r-- op/op.laeufer
#   1590 -rw-r--r-- op/op.nimzowitsch
#    635 -rw-r--r-- op/op.nordgam
#   2692 -rw-r--r-- op/op.philidor
#    616 -rw-r--r-- op/op.ponziani
#  11254 -rw-r--r-- op/op.reti
#   1536 -rw-r--r-- op/op.russisch
#    823 -rw-r--r-- op/op.schottisch
#  71561 -rw-r--r-- op/op.sizilian
#    935 -rw-r--r-- op/op.skandinav
#   4330 -rw-r--r-- op/op.spanisch
#    913 -rw-r--r-- op/op.ufimzew
#    626 -rw-r--r-- op/op.ungarische
#    594 -rw-r--r-- op/op.unregel
#   2030 -rw-r--r-- op/op.vierspring
#   1690 -rw-r--r-- op/op.wiener
#   4656 -rw-r--r-- op/op.zweispring
#   4548 -rw-r--r-- def.english
#   4581 -rw-r--r-- def.german
#   7830 -rw-r--r-- man
#  11920 -rw-r--r-- Makefile
#
if test -r _shar_seq_.tmp; then
	echo 'Must unpack archives in sequence!'
	echo Please unpack part `cat _shar_seq_.tmp` next
	exit 1
fi
# ============= README.eng ==============
if test -f 'README.eng' -a X"$1" != X"-c"; then
	echo 'x - skipping README.eng (File already exists)'
	rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting README.eng (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'README.eng' &&
X		    --------------------------------
X		    Installation off UnixChess V2.7:
X		    --------------------------------
X
o	Look up the 'Makefile' and make any necessary changes (e.g. if
X	you need other pathnames).
X
o	Do a test installation in the source directory by simply
X	typing 'make'.
X
o	If everything works fine, install finaly with 'make install'.
X	Important: Just copying the files for installation won't
X	work, because the pathnames won't be set up correctly.
X
o	If you want to install the manual, type 'make install_man'.
X	Unfortunately, I've only a german manual. Perhaps there is
X	someone who is good enough in english and german to translate
X	it and post it ?
X
o	Let the 'cron' run 'xchess -e' (expire) exactly once a day.
X
o	If you have any problems, send an email to 'ml@brumuc.muc.sub.org'.
X
X
X	
SHAR_EOF
chmod 0644 README.eng ||
echo 'restore of README.eng failed'
Wc_c="`wc -c < 'README.eng'`"
test 808 -eq "$Wc_c" ||
	echo 'README.eng: original size 808, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= README.ger ==============
if test -f 'README.ger' -a X"$1" != X"-c"; then
	echo 'x - skipping README.ger (File already exists)'
	rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting README.ger (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'README.ger' &&
X		    --------------------------------
X		    Installieren von UnixChess V2.7:
X		    --------------------------------
X
o	Im 'Makefile' Eintraege ggf. aendern (falls z.B. andere Pfade
X	gewuenscht sind).
X
o	Mit 'make' zum Test im aktuellen Directory installieren.
X
o	Mit 'make install' endgueltig installieren. WICHTIG: Nicht
X	einfach durch Kopieren der Files installieren, da dann die
X	Pfadnamen nicht richtig gesetzt werden !
X
o	Mit 'make install_man' Dokumentation installieren.
X
o	'xchess -e' (expire) einmal taeglich von 'cron' ausfuehren lassen.
X
o	Probleme, Verbesserungsvorschlaege, Inkompatibilitaeten bitte
X	an 'ml@brumuc.muc.sub.org' senden.
X
SHAR_EOF
chmod 0644 README.ger ||
echo 'restore of README.ger failed'
Wc_c="`wc -c < 'README.ger'`"
test 651 -eq "$Wc_c" ||
	echo 'README.ger: original size 651, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= ch/value.c ==============
if test ! -d 'ch'; then
    echo 'x - creating directory ch'
    mkdir 'ch'
fi
if test -f 'ch/value.c' -a X"$1" != X"-c"; then
	echo 'x - skipping ch/value.c (File already exists)'
	rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting ch/value.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'ch/value.c' &&
/****************************************************************/
/*								*/
/*	XChess V2.7: Stellung bewerten				*/
/*								*/
/*	(c) 1991 by Marc Laukien				*/
/*								*/
/****************************************************************/
X
#include "ch.h"			/* Def. des Schachspiels 	*/
#include "ph.h"			/* Def. der Spielphasen		*/
X
static long bewerte2();		/* Vorwaertsdeklaration		*/
X
/****************************************************************/
/*	Stellung bewerten					*/
/****************************************************************/
/*	Return:	Stellungwert					*/
/****************************************************************/
X
long bewerte(dat,pos)
X
SPDAT 	*dat;			/* Spieldaten	*/
BYTE	pos;			/* einzelne Position	*/
{
X	BYTE		i,j;		/* Zaehler		*/
X	long		wert=0L;	/* Wert der Position	*/
X
X	if(!pos)		/* komplett berechnenen ?	*/
X	for(j=0;j<8;j++)	/* alle Felder durchgehen	*/
X		for(i=0;i<8;i++)
X			wert += bewerte2(dat,i,j);	/* berechnen	*/
X	else             	/* nur eine Position berechnen	*/
X	{
X		i=_xpos(pos);			/* Koordinaten best.	*/
X		j=_ypos(pos);
X
X		wert = bewerte2(dat,i,j);	/* berechnen	*/
X	}
X
X	return(wert);		/* Stellungswert zurueckgeben	*/
}
X
static long bewerte2(dat,i,j)
X
SPDAT 	*dat;			/* Spieldaten	*/
BYTE	i,j;			/* zu bewertende Position	*/
{
X	static long fig_wert[]=	/* Wert der Figuren	*/
X	{0L,100L,100L,300L,300L,500L,500L,900L,MATT,MATT};
X
X	BYTE	fig;			/* Figur		*/
X	long	wert=0;			/* Wert der Position	*/
X	BYTE	pos;			/* Position		*/
X
X	pos=ZLEN*(j+RAND)+i+RAND;	/* Position berechnen	*/
X
X	fig=dat->brett[pos];		/* Figur bestimmen	*/
X
X	wert = fig_wert[_figur(fig)];	/* Wert der Figur 	*/
X
X	if(phase==EROEFF)		/* Eroeffnungsphase ?	*/
X	{
X		/**** Postionsboni Eroeffnung ****/
X		static long bau_add[][8]=
X		{
X		0L,	0L,	0L,	0L,	0L,	0L,	0L,	0L,
X		0L,	0L,	0L,	0L,	0L,	0L,	0L,	0L,
X		0L,	0L,	20L,	20L,	20L,	20L,	0L,	0L,
X		0L,	0L,	20L,	50L,	50L,	20L,	0L,	0L,
X		0L,	0L,	20L,	50L,	50L,	20L,	0L,	0L,
X		0L,	0L,	20L,	20L,	20L,	20L,	0L,	0L,
X		0L,	0L,	0L,	0L,	0L,	0L,	0L,	0L,
X		0L,	0L,	0L,	0L,	0L,	0L,	0L,	0L,
X		};
X
X		static long spr_add[][8]=
X		{
X		-50L,	0L,	0L,	0L,	0L,	0L,	0L,	-50L,
X		-20L,	0L,	0L,	0L,	0L,	0L,	0L,	-20L,
X		-20L,	0L,	0L,	50L,	50L,	0L,	0L,	-20L,
X		-20L,	10L,	40L,	50L,	50L,	40L,	10L,	-20L,
X		-20L,	10L,	30L,	50L,	50L,	30L,	10L,	-20L,
X		-20L,	0L,	30L,	10L,	10L,	30L,	0L,	-20L,
X		-20L,	0L,	0L,	0L,	0L,	0L,	0L,	-20L,
X		-50L,	0L,	0L,	0L,	0L,	0L,	0L,	-50L,
X		};
X
X		static long lae_add[][8]=
X		{
X		0L,	0L,	0L,	0L,	0L,	0L,	0L,	0L,
X		0L,	0L,	0L,	0L,	0L,	0L,	0L,	0L,
X		0L,	0L,	0L,	0L,	0L,	0L,	0L,	0L,
X		0L,	50L,	0L,	0L,	0L,	0L,	20L,	0L,
X		10L,	0L,	10L,	0L,	0L,	10L,	0L,	10L,
X		0L,	0L,	0L,	20L,	20L,	0L,	0L,	0L,
X		0L,	0L,	50L,	0L,	10L,	0L,	0L,	0L,
X		0L,	0L,	0L,	0L,	0L,	0L,	0L,	0L,
X		};	
X
X		static long koe_add[][8]=
X		{
X		-20L,	-20L,	-20L,	-20L,	-20L,	-20L,	-20L,	-20L,
X		-20L,	-20L,	-20L,	-20L,	-20L,	-20L,	-20L,	-20L,
X		-20L,	-20L,	-20L,	-20L,	-20L,	-20L,	-20L,	-20L,
X		-20L,	-20L,	-20L,	-20L,	-20L,	-20L,	-20L,	-20L,
X		-20L,	-20L,	-20L,	-20L,	-20L,	-20L,	-20L,	-20L,
X		-20L,	-20L,	-20L,	-20L,	-20L,	-20L,	-20L,	-20L,
X		-20L,	-20L,	-20L,	-20L,	-20L,	-20L,	-20L,	-20L,
X		-20L,	 60L,	 60L,	  0L,	-10L,	  0L,	 60L,	-20L,
X		};
X
X		switch(_figur(fig))		/* Positionsboni	*/
X		{
X		case BAU:			/* Bauer		*/
X		case XBAU:
X			wert += bau_add[_farbe(fig)==SCH?j:7-j][i];
X			break;
X
X		case SPR:			/* Springer		*/
X			wert += spr_add[_farbe(fig)==SCH?j:7-j][i];
X			break;
X
X		case LAE:			/* Laeufer		*/
X			wert += lae_add[_farbe(fig)==SCH?j:7-j][i];
X			break;
X
X		case KOE:			/* Koenig		*/
X		case XKOE:
X			wert += koe_add[_farbe(fig)==SCH?j:7-j][i];
X			break;
X		}
X	}
X	else if(phase==MITTEL)			/* Mittelspiel ?	*/
X	{
X		/*** Reihenboni Mittelspiel	(gilt fuer Turm)	***/
X		static long add[]={0L,5L,10L,15L,20L,25L,40L,50L};
X
X		if(!_istkoe(fig))
X			wert += (fig_wert[_figur(fig)]*
X			add[_farbe(fig)==WEI ? j:7-j])/fig_wert[TUR];
X	}
X	else if(phase==ENDSPI || phase==WKOEOO || phase==SKOEOO)	
X	{					/* Endspiel ?		*/
X		/*** Positionsboni fuer Koenig				***/
X		static long koe_add[][8]=
X		{
X		-80L,	-60L,	-30L,	-30L,	-30L,	-30L,	-60L,	-80L,
X		-60L,	-30L,	-10L,	-10L,	-10L,	-10L,	-30L,	-60L,
X		-30L,	-10L,	  0L,	  0L,	  0L,	  0L,	-10L,	-30L,
X		-30L,	-10L,	  0L,	  0L,	  0L,	  0L,	-10L,	-30L,
X		-30L,	-10L,	  0L,	  0L,	  0L,	  0L,	-10L,	-30L,
X		-30L,	-10L,	  0L,	  0L,	  0L,	  0L,	-10L,	-30L,
X		-60L,	-30L,	-10L,	-10L,	-10L,	-10L,	-30L,	-30L,
X		-80L,	-60L,	-30L,	-30L,	-30L,	-30L,	-60L,	-60L,
X		};
X
X		/*** Reihenboni Endspiel fuer Bauer			***/
X		static long add[]={0L,5L,10L,15L,20L,25L,30L,35L};
X
X		if(_istbau(fig))			/* Bauern vor 	*/
X			wert += add[_farbe(fig)==WEI ? j:7-j];
X
X		if(phase==WKOEOO || phase==SKOEOO)	/* Koe. o. Offiziere*/
X		if(_istkoe(fig))
X		{
X			int 	abstand;
X
X			abstand=abs((int)(_xpos(dat->wkpos)-_xpos(dat->skpos)))
X			       +abs((int)(_ypos(dat->wkpos)-_ypos(dat->skpos)));
X
X			if(_istwei(fig))
X			{
X			if(phase==WKOEOO)	/* nicht an den Rand	*/
X				wert+= koe_add[_farbe(fig)==SCH?j:7-j][i];
X			else			/* Koenig in Opposition	*/
X				wert-= abstand * 10;
X			}
X			else if(_istsch(fig))
X			{
X			if(phase==SKOEOO)	/* nicht an den Rand	*/
X				wert+= koe_add[_farbe(fig)==SCH?j:7-j][i];
X			else			/* Koenig in Opposition	*/
X				wert-= abstand * 10;
X			}
X		}
X	}
X
X	wert *= _farbe(fig) == WEI ? 1L:-1L;	/* Vorzeichen		*/
X
X	return(wert);
}
SHAR_EOF
chmod 0644 ch/value.c ||
echo 'restore of ch/value.c failed'
Wc_c="`wc -c < 'ch/value.c'`"
test 5280 -eq "$Wc_c" ||
	echo 'ch/value.c: original size 5280, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= ch/main.c ==============
if test -f 'ch/main.c' -a X"$1" != X"-c"; then
	echo 'x - skipping ch/main.c (File already exists)'
	rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting ch/main.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'ch/main.c' &&
/****************************************************************/
/*								*/
/*	XChess V2.7: Hauptprogramm				*/
/*								*/
/*	(c) 1991 by Marc Laukien				*/
/*								*/
/****************************************************************/
X
#include <string.h>
#include "ch.h"			/* Def. des Schachspiels 	*/
X
int	opnr;			/* Anzahl der Eroeffnungen	*/
int	testopnr;		/* Eroeffnungsnummer zum testen */
WORD	*op[MAXOP];		/* Zeiger auf die Eroeffnungen	*/
BYTE	op_fa[MAXOP];		/* Farbe fuer die Eroeff. gilt	*/
int	noop;			/* 1-Keine Eroeffnungsbib. mehr	*/
SPDAT	spdat;			/* Alle Spieldaten 		*/
ARCHIV	*archiv[MAXSP];		/* Archiv der Positionen	*/
int	phase;			/* Spielphase			*/
int	zaehler;		/* Antwortzaehler		*/
int	compzuege;		/* Computerzuege		*/
long	varianten;		/* Zaehler fuer die Varianten	*/
long	zeit;			/* Dauer des letzten Zuges	*/
long	varprosek;		/* Varianten pro Sekunde	*/
int	stufe=0;		/* Spielstufe			*/
int	beende;			/* Falls 1 Denkvorgang beenden	*/
WORD	best_so_far;		/* Bester Zug bis jetzt		*/
X
int	mode=2+4+8+32+128;	/* Modus			*/
X				/* 1   :Analyse	ausfuehrlich	*/
X				/* 2   :Alpha-Beta-Abschneidung	*/
X				/* 4   :Vorsortieren		*/
X				/* 8   :Stufenanpassung		*/
X				/* 16  :Koenigsbedrohung immer	*/
X				/*      ueberpruefen		*/
X				/* 32  :Eroeffnungsbib. ein	*/
X				/* 64  :Eroeffnungsnr = testopnr*/
X				/* 128 :Analyse einfach		*/
X
X				/* Status des letzten Zuges:	*/
int	schlag;			/* falls 1 wurde geschlagen	*/
X				/* oder befoerdert		*/
int	gabel;			/* Bauernspiess oder		*/
X				/* Springergabel		*/
X
X				/* maximal und minimale Rechentiefe	*/
int	mintiefe[]={2,2,  3,3,  4,4,  5,5,   6,6 };
int	maxtiefe[]={4,6,  6,8,  6,8,  8,10,  8,10};
X
extern	long	time();
extern	char	*malloc();
extern	char	*memcpy();
extern	void	free();
X
/****************************************************************/
/*	Hauptprogramm						*/
/****************************************************************/
/*	Return: Anzahl der Antworten in ret			*/
/****************************************************************/
X
schach(str,ret)
X
char *str;					/* Kommandostring	*/
char *ret[];					/* Antworten		*/
{
X	char cmd[STRLEN];			/* Kommando		*/
X
X	zaehler=0;				/* noch keine Antwort	*/
X	beende=0;				/* nicht beenden	*/
X	best_so_far=(WORD)0;			/* noch kein Zug	*/
X
X	sscanf(str,"%s",cmd);			/* Kommando einlesen	*/
X
X	strcpy(ret[zaehler],"ok");		/* loeschen		*/
X
X	if(!strcmp(cmd,"init"))
X		init(&spdat,1);			/* Initialisierungen	*/
X	else if(!strcmp(cmd,"loeschen"))
X		init(&spdat,0);			/* Brett loeschen	*/
X	else if(!strcmp(cmd,"brett"))
X		brett_aus(&spdat,ret);		/* Brett zeigen		*/
X	else if(!strcmp(cmd,"info"))
X		info_aus(&spdat,ret);   	/* Informationen	*/
X	else if(!strcmp(cmd,"status"))
X		status_aus(&spdat,ret);  	/* Statusinformationen	*/
X	else if(!strcmp(cmd,"weiss"))
X	{
X		spdat.farbe=WEI;	  	/* Weiss am Zug		*/
X		noop=0;
X	}
X	else if(!strcmp(cmd,"schwarz"))
X	{
X		spdat.farbe=SCH;	  	/* Schwarz am Zug	*/
X		noop=0;
X	}
X	else if(!strcmp(cmd,"testbib"))		/* Bibl. testen		*/
X	{
X		if(!bib_test())
X			strcpy(ret[zaehler++],"?");	/* Fehler	*/
X	}
X	else if(!strcmp(cmd,"zurueck"))   	/* Zug zurueck		*/
X	{
X		if(!hole_zurueck(&spdat,spdat.zuege-1))
X			strcpy(ret[zaehler++],"?");	/* Fehler	*/
X		else
X		{
X			free(archiv[spdat.zuege+1]);	/* freigeben	*/
X			archiv[spdat.zuege+1]=(ARCHIV *)0;
X
X			noop=OPTRYS;		/* Eroeffnungsbibl. ein	*/
X			varianten=0;		/* Keine Varianten	*/
X		}
X	}
X	else if(!strcmp(cmd,"zliste"))
X	{
X		zugliste(&spdat,(BYTE)0);	/* Zugliste erstellen	*/
X		zugliste_aus(&spdat,0,ret);	/* Zugliste zeigen	*/
X	}
X	else if(!strcmp(cmd,"spiel"))
X	{
X		int i;
X
X		for(i=1;i<=spdat.zuege;i++)	/* alle Zuege durchgehen*/
X			sprintf(ret[zaehler++],"%3d: %s",i
X			,wandle(_apos(archiv[i]->lzug)
X			,_npos(archiv[i]->lzug)));
X	}
X	else if(!strcmp(cmd,"save"))
X	{
X		char name[STRLEN];
X
X		name[0]=0;				/* loeschen	*/
X		strcpy(name,str+strlen(cmd));		/* kopieren	*/
X
X		if(name[0]==0)				/* kein Name ?	*/
X			strcpy(ret[zaehler++],"?");	/* Fehler	*/
X		else if(!save_game(name))		/* Speichern	*/
X			strcpy(ret[zaehler++],"?");	/* Fehler	*/
X	}
X	else if(!strcmp(cmd,"load"))
X	{
X		char name[STRLEN];
X
X		name[0]=0;				/* loeschen	*/
X		strcpy(name,str+strlen(cmd));		/* kopieren	*/
X
X		if(name[0]==0)				/* kein Name ?	*/
X			strcpy(ret[zaehler++],"?");	/* Fehler	*/
X		else if(!load_game(name))		/* Laden	*/
X			strcpy(ret[zaehler++],"?");	/* Fehler	*/
X	}
X	else if(!strcmp(cmd,"loadinfo"))
X	{
X		SPDAT	dat;			/* Spieldaten		*/
X		char 	name[STRLEN];
X
X		name[0]=0;				/* loeschen	*/
X		strcpy(name,str+strlen(cmd));		/* kopieren	*/
X
X		if(name[0]==0)				/* kein Name ?	*/
X			strcpy(ret[zaehler++],"?");	/* Fehler	*/
X		else
X		{
X			if(!load_spdat(name,&dat))	/* Laden	*/
X				strcpy(ret[zaehler++],"?");/* Fehler	*/
X			else
X				info_aus(&dat,ret);   	/* Informationen*/
X		}
X	}
X	else if(!strcmp(cmd,"ziehe"))
X	{
X		WORD zug;
X
X		if(!(zug=wandle_inv(str+strlen(cmd))))
X			strcpy(ret[zaehler++],"?");	/* Fehler	*/
X		else if(!zug_test(&spdat,zug))		/* Testen	*/
X			strcpy(ret[zaehler++],"?");	/* Fehler	*/
X		else
X		{
X			ziehe(&spdat,zug);		/* ziehen	*/
X			archiviere(&spdat);		/* speichern	*/
X		}
X	}
X	else if(!strcmp(cmd,"setze"))
X	{
X		BYTE pos;				/* Position	*/
X		char *str2;
X		BYTE fig;                            	/* Figur	*/
X
X		str2=str+strlen(cmd);
X		while(*str2==' ')
X			str2++;
X
X		if((fig=wandle_fig(*str2))==0)		/* Figur holen	*/
X			strcpy(ret[zaehler++],"?");	/* Fehler	*/
X		else
X		{
X			str2++;
X
X			if(!(pos=(BYTE)wandle_inv(str2)))
X				strcpy(ret[zaehler++],"?");/* Fehler	*/
X			else
X			{
X			if(	/* Keine 2 Koenige !		*/
X			(_istkoe(fig) && _istwei(fig)
X			&& spdat.wkpos!=(BYTE)0) ||
X			(_istkoe(fig) && _istsch(fig)
X			&& spdat.skpos!=(BYTE)0))
X					strcpy(ret[zaehler++],"?");/* Fehler */
X			else
X			{
X				spdat.brett[pos]=fig;	/* setzen	*/
X				noop=0;		/* Bib. schliessen	*/
X
X				if(pos==spdat.wkpos) /* Koenig loeschen ? */
X					spdat.wkpos=(BYTE)0;
X
X				if(pos==spdat.skpos) /* Koenig loeschen ? */
X					spdat.skpos=(BYTE)0;
X
X				if(_istkoe(fig)) 	/* Koenig ?	*/
X				{ 	/* Positionen eintragen	*/
X					if(_istwei(fig))
X						spdat.wkpos=pos;
X
X					if(_istsch(fig))
X						spdat.skpos=pos;
X				}
X			}
X			}
X		}
X	}
X	else if(!strcmp(cmd,"comp"))
X	{
X		WORD	bzug[MAXTIEFE];	/* Beste Zugkombination		*/
X
X		varianten=0;
X		zeit=time((long *)0);			/* Zeit merken	*/
X
X		spdat.wert=bewerte(&spdat,0);		/* Stellungswert*/
X		eff_stufe(&spdat);			/* Rechentiefe	*/
X
X		if((spdat.bzug=bib_zug())==(WORD)0)/* Kein Zug in Bib. ?*/
X		{
X			comp_zug(&spdat,spdat.farbe==WEI ? MATT:-MATT,
X			bzug);				/* besten Zug 	*/
X		}
X
X		if(zug_test(&spdat,spdat.bzug))		/* Testen	*/
X		{
X			ziehe(&spdat,spdat.bzug);	/* ziehen	*/
X			archiviere(&spdat);		/* speichern	*/
X
X			zeit=time((long *)0)-zeit;	/* Zeitdifferenz*/
X			if(varianten>0)			/* Computerzug ?*/
X			if(++compzuege<=50)		/* Kein Ueberlauf */
X			varprosek+=varianten/((long)zeit>0 ? (long)zeit:1L);
X		}
X		else	/* Fehler, z.B. in der Bibliothek ?	*/
X			noop=0;	/* schliessen	*/
X	}
X	else if(!strcmp(cmd,"bliste"))
X	{
X		WORD	bzug[MAXTIEFE];	/* Beste Zugkombination		*/
X		varianten=0;
X
X		zeit=time((long *)0);			/* Zeit merken	*/
X		spdat.wert=bewerte(&spdat,0);		/* Stellungswert*/
X		eff_stufe(&spdat);			/* Rechentiefe	*/
X		comp_zug(&spdat,spdat.farbe==
X		WEI ? MATT:-MATT,bzug);			/* besten Zug 	*/
X		zeit=time((long *)0)-zeit;		/* Zeitdifferenz*/
X		if(varianten>0)				/* Computerzug ?*/
X		if(++compzuege<=50)			/* Kein Ueberlauf */
X		varprosek+=varianten/((long)zeit>0 ? (long)zeit:1L);
X		zugliste_aus(&spdat,1,ret);		/* Zugliste zeigen*/
X	}
X	else if(!strcmp(cmd,"modus"))	/* Modus einstellen	*/
X		sscanf(str+strlen(cmd),"%d",&mode);
X	else if(!strcmp(cmd,"stufe"))	/* Stufe einstellen	*/
X	{
X		sscanf(str+strlen(cmd),"%d",&stufe);
X		eff_stufe(&spdat);	/* Rechentiefe	*/
X	}
X	else if(!strcmp(cmd,"wert"))
X		sprintf(ret[zaehler++],"%ld",bewerte(&spdat,0));
X	else
X		strcpy(ret[zaehler++],"?");
X
X	return(zaehler);		/* Anzahl der Antworten zurueck	*/
}
SHAR_EOF
chmod 0644 ch/main.c ||
echo 'restore of ch/main.c failed'
Wc_c="`wc -c < 'ch/main.c'`"
test 7880 -eq "$Wc_c" ||
	echo 'ch/main.c: original size 7880, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= ch/move.c ==============
if test -f 'ch/move.c' -a X"$1" != X"-c"; then
	echo 'x - skipping ch/move.c (File already exists)'
	rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting ch/move.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'ch/move.c' &&
/****************************************************************/
/*								*/
/*	XChess V2.7: Zug ausfuehren				*/
/*								*/
/*	(c) 1991 by Marc Laukien				*/
/*								*/
/****************************************************************/
X
#include "ch.h"			/* Def. des Schachspiels */
X
/****************************************************************/
/*	Zug ausfuehren						*/
/****************************************************************/
/*	Return:	1: es wurde Rochiert oder e.p. geschl.		*/
/****************************************************************/
X
int	ziehe(dat,zug)
X
SPDAT	*dat;				/* Spieldaten 	*/
WORD	zug;				/* auszuf. Zug	*/
{
X	BYTE	afig;			/* alte Figur	*/
X	BYTE	npos,apos;		/* neue und alte Pos.	*/
X	int	epro=0;			/* falls ep. od. Roch.	*/
X
X					/* Status des letzten Zuges:	*/
X	schlag=0;			/* falls 1 wurde geschlagen	*/
X					/* oder befoerdert		*/
X	gabel=0;			/* Bauernspiess oder		*/
X					/* Springergabel		*/
X
X	npos=_npos(zug);		/* Pos. berechnen	*/
X	apos=_apos(zug);
X
X	afig=dat->brett[apos];		/* alte Figur holen	*/
X
X	switch(_figur(afig))   		/* Umwandlungen ?	*/
X	{
X	case BAU:			/* Befoerderung		*/
X		if(_istspz(dat->brett[npos+ZLEN]))
X		{
X			afig=DAM|WEI;
X			schlag=1;
X		}
X		else if(_istspz(dat->brett[npos-ZLEN]))
X		{
X			afig=DAM|SCH;
X			schlag=1;
X		}
X					/* schlagen en passant	*/
X		else if(_istlee(dat->brett[npos]))
X			switch((short)npos-(short)apos)
X			{
X			case 13:	/* rechts loeschen	*/
X			case -11:
X				dat->brett[apos+1]=LEE;
X				schlag=1;
X				epro=1;
X				break;
X
X			case 11:	/* links loeschen	*/
X			case -13:
X				dat->brett[apos-1]=LEE;
X				schlag=1;
X				epro=1;
X				break;
X			}
X
X		switch((short)npos-(short)apos)
X		{
X		case 12:	/* Bauernspiess	weiss ?	*/
X			if(_istnsch(dat->brett[npos+13]) &&
X			  !_istbau(dat->brett[npos+13]) &&
X			   _istnsch(dat->brett[npos+11]) &&
X			  !_istbau(dat->brett[npos+11]))
X				gabel=1;
X			break;
X
X		case -12:	/* Bauernspiess	schwarz ?*/
X			if(_istnwei(dat->brett[npos-13]) &&
X			  !_istbau(dat->brett[npos-13]) &&
X			   _istnwei(dat->brett[npos-11]) &&
X			  !_istbau(dat->brett[npos-11]))
X				gabel=1;
X			break;
X		}
X		break;
X
X	case XBAU:			/* Spezialfig. normal	*/
X		afig=BAU | _farbe(afig);
X		switch((short)npos-(short)apos)
X		{
X		case 12:	/* Bauernspiess	weiss ?	*/
X			if(_istnsch(dat->brett[npos+13]) &&
X			  !_istbau(dat->brett[npos+13]) &&
X			   _istnsch(dat->brett[npos+11]) &&
X			  !_istbau(dat->brett[npos+11]))
X				gabel=1;
X			break;
X
X		case -12:	/* Bauernspiess	schwarz ?*/
X			if(_istnwei(dat->brett[npos-13]) &&
X			  !_istbau(dat->brett[npos-13]) &&
X			   _istnwei(dat->brett[npos-11]) &&
X			  !_istbau(dat->brett[npos-11]))
X				gabel=1;
X			break;
X		}
X		break;
X
X	case XTUR:
X		afig=TUR | _farbe(afig);
X		break;
X
X	case XKOE:
X		afig=KOE | _farbe(afig);
X
X		if((short)npos-(short)apos==2)	/* kurze Rochade	*/
X		{
X			epro=1;
X			dat->brett[apos+1]=TUR | _farbe(afig);
X			dat->brett[npos+1]=LEE;
X		}
X		if((short)npos-(short)apos==-2)	/* lange Rochade	*/
X		{
X			epro=1;
X			dat->brett[apos-1]=TUR | _farbe(afig);
X			dat->brett[npos-2]=LEE;
X		}
X
X	case KOE:				/* Koenigspositionen	*/
X		if(_istwei(afig))
X			dat->wkpos=npos;
X		else
X			dat->skpos=npos;
X		break;
X	}
X
X	if(!_istlee(dat->brett[npos]))		/* schlagen ?		*/
X	{
X		schlag=1;
X		if(_istkoe(dat->brett[npos]))	/* Koenig geschlagen ? 	*/
X						/* (theor., d.h. matt)	*/
X		{
X			if(_istwei(dat->brett[npos]))
X				dat->wkpos=(BYTE)0;	/* loeschen	*/
X			else
X				dat->skpos=(BYTE)0;	/* loeschen	*/
X		}
X	}
X	dat->brett[apos]=LEE;			/* loeschen		*/
X	dat->brett[npos]=afig;			/* neu setzen		*/
X	dat->farbe=dat->farbe==WEI ? SCH:WEI;	/* Farbe aendern	*/
X	dat->lzug=zug;				/* letzter Zug		*/
X	dat->zuege++;				/* ein Zug mehr		*/
X
X	return(epro);
}
X
/****************************************************************/
/*	Zug testen						*/
/****************************************************************/
/*	Return: 1: Zug moeglich,    0: nicht mgl.		*/
/****************************************************************/
X
int	zug_test(dat,zug)
X
SPDAT 	*dat;				/* Spieldaten		*/
WORD 	zug;				/* zu testender Zug	*/
{
X	int 	anz;			/* Anzahl der Zuege	*/
X
X	if(dat->zuege+5 >= MAXSP)	/* Grenze erreicht	*/
X		return(0);		/* +5 ist Sicherheit	*/
X
X	anz=zugliste(dat,_apos(zug));	/* Liste holen		*/
X
X	while(--anz>=0)			/* alle testen		*/
X		if(zug==dat->zlist[anz])
X			return(1);
X
X	return(0);                	/* nicht gefunden	*/
}
SHAR_EOF
chmod 0644 ch/move.c ||
echo 'restore of ch/move.c failed'
Wc_c="`wc -c < 'ch/move.c'`"
test 4354 -eq "$Wc_c" ||
	echo 'ch/move.c: original size 4354, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= ch/comp.c ==============
if test -f 'ch/comp.c' -a X"$1" != X"-c"; then
	echo 'x - skipping ch/comp.c (File already exists)'
	rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting ch/comp.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'ch/comp.c' &&
/****************************************************************/
/*								*/
/*	XChess V2.7: Computerzug				*/
/*								*/
/*	(c) 1991 by Marc Laukien				*/
/*								*/
/****************************************************************/
X
#include "ch.h"			/* Def. des Schachspiels 	*/
X
#ifdef	ANALYSE
static void monitor();
#endif
X
/****************************************************************/
/*	Computerzug bestimmen					*/
/****************************************************************/
/*	Return:	Bewertung des Zugs				*/
/****************************************************************/
X
long	comp_zug(dat,erw,bzug)
X
SPDAT 	*dat;					/* Spieldaten		*/
long	erw;					/* Erwartungswert	*/
WORD	bzug[];					/* beste Zugkombination */ 
{
X	SPDAT		copy;			/* Kopie der Spieldaten	*/
X	SPDAT		*cdat;			/* Zeiger auf Kopie	*/
X	WORD		bzugliste[MAXZUG][MAXTIEFE];
X						/* Liste der Zugkomb.	*/
X	long		wert,maxwert;		/* Bewertung 		*/
X	int		anz=0,best=0;		/* Zaehler, bester Zug	*/
X	register	i,j,k;			/* Zaehler		*/
X	WORD		azug=0,nzug;		/* alter und neuer Zug	*/
X
X	if(mode&4 && dat->minstufe >= 2)	/* Vorsortieren ?	*/
X		anz=sortliste(dat,dat->minstufe-1);
X	else
X		anz=zugliste(dat,(BYTE)0);
X
X	if(!anz)
X	{
X		/* MATT */
X		if(dat->farbe==WEI)
X			if(bedrohung(dat,dat->wkpos)||dat->wkpos==(BYTE)0)
X				return(-MATT);
X
X		if(dat->farbe==SCH)
X			if(bedrohung(dat,dat->skpos)||dat->skpos==(BYTE)0)
X				return(MATT);
X
X		/* PATT */
X		return(0L);		/* unentschieden	*/
X	}
X
X	cdat= &copy;			/* Zeiger bestimmen	*/
X
X	maxwert=dat->farbe==WEI?-2*MATT:2*MATT;/* min. Bewertung	*/
X	/* 2 * matt damit mindestens ein Zug bei sicherem Matt aus-	*/
X	/* gegeben wird.						*/
X
X	for(i=0;i<anz;i++)		/* alle Zuege durchgehen	*/
X	{
X		/* alles wichtige kopieren	*/
X
X		if(azug)		/* nur Veraenderungen kopieren	*/
X		{
X			BYTE ap,np;
X
X			ap=_apos(azug);
X			np=_npos(azug);
X
X			cdat->brett[ap] = dat->brett[ap];
X			cdat->brett[np] = dat->brett[np];
X		}
X		else			/* 1. Kopie ?	*/
X			for(j=0;j<GROE;j++)
X				cdat->brett[j]=dat->brett[j];
X
X		cdat->wkpos	=dat->wkpos;
X		cdat->skpos	=dat->skpos;
X		cdat->farbe	=dat->farbe;
X		cdat->lzug      =dat->lzug;
X		cdat->zuege	=dat->zuege;
X		cdat->minstufe	=dat->minstufe-1;	/* Stufe weniger*/
X		cdat->maxstufe	=dat->maxstufe-1;
X		cdat->vorher	=dat;			/* letzter Zug	*/
X
X		/**** Bewertungs-Algorithmus ***/
X
X		if(!ziehe(cdat,nzug=dat->zlist[i]))	/* ziehe	*/
X		{				/* Differenz bewerten	*/
X			long	add;
X
X			add = -bewerte(dat,_apos(nzug));
X
X			if(!_istlee(dat->brett[_npos(nzug)]))
X							/* geschl. ?	*/
X				add -= bewerte(dat,_npos(nzug));
X
X			add += bewerte(cdat,_npos(nzug));
X
X			azug=nzug;		/* Zug merken		*/
X
X			add = (add*(20L+(long)cdat->maxstufe))/20L;
X			/* ^ addiert fuer jede Stufe 5 % des Wertes.	*/
X			/* Dient dazu, dass gute Zuege zuerst		*/
X			/* ausgefuehrt werden.				*/
X
X			cdat->wert = dat->wert + add;
X		}
X		else				/* komplett bewerten	*/
X		{
X			azug=(WORD)0;
X			cdat->wert = bewerte(cdat,(BYTE)0);
X		}
X
X		/**** STUFE ERHOEHEN fuer spezielle Zuege	****/
X
X 		if(cdat->minstufe <= 0)	/* 1 oder 2 Stufen erweitern ?	*/
X		{
X		if(cdat->maxstufe > 0)
X		{
X			if(schlag)	/* geschlagen oder Befoerderung	*/
X				cdat->minstufe++; /* eine Stufe mehr	*/
X			if(gabel)	/* Gabel oder Spiess gefunden 	*/
X				cdat->minstufe+=2; /* 2 Stufen mehr	*/
X		}
X		}
X		else if(cdat->minstufe <= 1) /* 1 Stufe erweitern ? 	*/
X		{
X		if(cdat->maxstufe > 1)
X			if(gabel)	/* Gabel oder Spiess gefunden 	*/
X				cdat->minstufe++; /* 1 Stufe mehr	*/
X		}
X
X		/**** ENDE STUFE ERHOEHEN fuer spezielle Zuege	****/
X
X		if(mode & 128)			/* einfache Analyse ?	*/
X			bzugliste[i][1]=(WORD)0;/* loeschen		*/
X
X		if((&spdat==dat || &spdat==dat->vorher) /* 1. oder 2. Zug */
X		&& (dat->maxstufe != dat->minstufe)) /* nicht Vorsortierung */
X		{					/* 3fache Wdh ?	*/
X			for(j=spdat.zuege;j>=0;j--)	/* Wdh. finden	*/
X			if(archiv[j]->wdh != -1)
X			{
X				for(k=0;k<GROE;k++)
X					if(cdat->brett[k]!=archiv[j]->brett[k])
X						break;
X
X				if(k==GROE)
X					break;	/* gefunden		*/
X			}
X
X			if(j > -1)		/* 3-fache Wiederholung	*/
X				wert=0L;	/* Remis		*/
X			else
X				wert=comp_zug(cdat,maxwert,&bzugliste[i][1]);
X		}
X		else if(cdat->minstufe<=0)	/* Keine Stufe weiter ?	*/
X		{
X			varianten++;	  	/* Eine Variante mehr	*/
X			wert=cdat->wert		/* Keine Stufe weiter	*/
X			+(rand()&0x7)-4;	/* Zufallskomponente 	*/
X		}
X		else				/* Eine Stufe weiter	*/
X			wert=comp_zug(cdat,maxwert,&bzugliste[i][1]);
X
X		dat->blist[i]=wert;		/* Bewertungsliste	*/
X
X		/**** ENDE Bewertungs-Algorithmus ****/
X
X		/**** MINIMAX-Algorithmus ****/
X
X		if(beende)			/* beenden ?		*/
X			break;
X		else if(dat->farbe==WEI)  	/* beste Bew. best.	*/
X		{
X			if(maxwert<wert)
X			{
X			maxwert=wert;
X			best=i;
X
X			/* Bester Zug bis jetzt	*/
X			if(dat == &spdat)
X				best_so_far=nzug;
X
#ifdef	ANALYSE		/* Monitorfunktion: einfache Analyse	*/
X			if(mode & 128 && dat == &spdat)
X			{
X				char str[STRLEN];
X
X				bzugliste[i][0]=nzug;
X				strcpy(str,kombination(dat,bzugliste[i]));
X				sprintf(str+strlen(str)," %ld",maxwert);
X				ANALYSE(str);
X			}				/* ausgeben	*/
#endif
X			}
X		}
X		else
X		{
X			if(maxwert>wert)
X			{
X			maxwert=wert;
X			best=i;
X
X			/* Bester Zug bis jetzt	*/
X			if(dat == &spdat)
X				best_so_far=nzug;
X
#ifdef	ANALYSE		/* Monitorfunktion: einfache Analyse	*/
X			if(mode & 128 && dat == &spdat)
X			{
X				char str[STRLEN];
X
X				bzugliste[i][0]=nzug;
X				strcpy(str,kombination(dat,bzugliste[i]));
X				sprintf(str+strlen(str)," %ld",maxwert);
X				ANALYSE(str);
X			}				/* ausgeben	*/
#endif
X			}
X		}
X
X		/**** Ende MINIMAX ****/
X
X		/**** ALPHA-BETA - Abschneidung	****/
X
X		if(wert >= erw && dat->farbe==WEI && mode&2)
X		{
#ifdef	ANALYSE
X			if(mode & 1)	/* Monitorfunktion	*/
X				monitor(cdat,wert,"Abbruch");
#endif
X			break;
X		}
X		else if(wert <= erw && dat->farbe==SCH && mode&2)
X		{
#ifdef	ANALYSE
X			if(mode & 1)	/* Monitorfunktion	*/
X				monitor(cdat,wert,"Abbruch");
#endif
X			break;
X		}
X
X		/**** Ende ALPHA-BETA - Algorithmus	****/
X
#ifdef	ANALYSE
X		if(mode & 1)
X			monitor(cdat,wert,"");	/* Monitorfunktion	*/
#endif
X	}
X
X	if(beende)			/* Beenden ?	*/
X		if(dat == &spdat)	/* Bester Zug	*/
X			dat->bzug=best_so_far;
X
X	dat->bzug = dat->zlist[best];		/* besten Zug eintragen	*/
X
#ifdef	ANALYSE		/* Monitorfunktion: einfache Analyse	*/
X	if(mode & 128)	/* einfache Analyse ?	*/
X	{
X		bzug[i=0]=dat->bzug;			/* merken	*/
X		while(bzugliste[best][++i]!=(WORD)0)
X			bzug[i]=bzugliste[best][i];	/* kopieren	*/
X		bzug[i]=(WORD)0;			/* beenden	*/
X	}
#endif
X
X	return(maxwert);			/* beste Bewertung	*/
}
X
#ifdef	ANALYSE
static void monitor(dat,wert,text)
X
SPDAT 	*dat;
long	wert;
char	*text;
{
X	SPDAT 	*ptr;		/* vorheriger Datensatz	*/
X	int 	i=0;      	/* Zaehler		*/
X	SPDAT	*ptrlist[20];	/* Liste mit allen Pointern	*/
X	char	str[STRLEN];	/* String		*/
X
X	ptr=dat;		/* letzte Daten		*/
X	str[0]=0;		/* loeschen		*/
X
X	while(ptr->vorher != (SPDAT *)0) /* zum Anf.	*/
X	{
X		ptrlist[i++]=ptr;
X		ptr= ptr->vorher;
X	}
X
X	while(--i>=0)		/* String erstellen	*/
X	{
X		sprintf(str+strlen(str),"%s%c",
X		wandle(_apos(ptrlist[i]->lzug),(BYTE)0),
X		_istlee(ptrlist[i]->vorher->
X		brett[_npos(ptrlist[i]->lzug)]) ? '-':'x');
X
X		sprintf(str+strlen(str),"%s ",
X		wandle(_npos(ptrlist[i]->lzug),(BYTE)0));
X	}
X
puts(str);
X	printf(/*str+strlen(str),*/" %ld %s",wert,text);
puts("");
X	/*ANALYSE(str);		/* ausgeben		*/
}
#endif
SHAR_EOF
chmod 0644 ch/comp.c ||
echo 'restore of ch/comp.c failed'
Wc_c="`wc -c < 'ch/comp.c'`"
test 7250 -eq "$Wc_c" ||
	echo 'ch/comp.c: original size 7250, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= ch/utility.c ==============
if test -f 'ch/utility.c' -a X"$1" != X"-c"; then
	echo 'x - skipping ch/utility.c (File already exists)'
	rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting ch/utility.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'ch/utility.c' &&
/****************************************************************/
/*								*/
/*	XChess V2.7: Utilities					*/
/*								*/
/*	(c) 1991 by Marc Laukien				*/
/*								*/
/****************************************************************/
X
#include <string.h>
#include <stdio.h>
#include <ctype.h>
#include "ch.h"			/* Def. des Schachspiels */
X
/****************************************************************/
/*	Brett ausgeben						*/
/****************************************************************/
X
void	brett_aus(dat,ret)
X
SPDAT	*dat;					/* Spieldaten	*/
char	*ret[];					/* Antworten	*/
{
X	BYTE		i,j;			/* Zaehler 	*/
X	BYTE		fig;			/* Figur	*/
X	char		c;			/* Zeichen fuer Figur	*/
X	char 		str[STRLEN];		/* String fuer Figur	*/
X	static 	char	figtab[]=".bbslttdkk";
X						/* Figurtabelle	*/
X
X	for(j=7;j!=0xff;j--)			/* ausgeben	*/
X	{
X		ret[zaehler][0]=0;		/* beenden	*/
X
X		for(i=0;i<8;i++)
X		{
X			fig=dat->brett[(j+RAND)*ZLEN+i+RAND];
X			c=figtab[fig&(~(SCH | WEI))];	/* Figur o. Farbe */
X
X			if(_istsch(fig))
X				c += 'A'-'a';	/* gross machen	*/
X
X			sprintf(str,"%c ",c);	/* Antwort herstellen	*/
X			strcat(ret[zaehler],str);
X		}
X
X		zaehler++;
X	}
}
X
/****************************************************************/
/*	Informationen ausgeben					*/
/****************************************************************/
X
void	info_aus(dat,ret)
X
SPDAT	*dat;					/* Spieldaten	*/
char	*ret[];					/* Antworten	*/
{
X	SPDAT datc;				/* Spieldaten	*/
X
X	eff_stufe(dat);				/* Stufe einstellen	*/
X	sprintf(ret[zaehler++],
X
X	"%c",dat->farbe==WEI?'w':'s');		/* Farbe am Zug		*/
X
X	sprintf(ret[zaehler++],
X	"%d",dat->zuege);			/* Anz. der Zuege	*/
X
X	sprintf(ret[zaehler++],			/* Bewertung		*/
X	"%ld",bewerte(dat,(BYTE)0));
X
X	sprintf(ret[zaehler++],"%ld",varianten);	/* Anz. d. Var.	*/
X
X	sprintf(ret[zaehler++],"%ld",			/* Var. / Sek.	*/
X	varianten/((long)zeit>0 ? (long)zeit:1L));
X
X	sprintf(ret[zaehler++],"%ld",			/* Var. / Sek.	*/
X	varprosek/(long)(compzuege > 0 ?		/* gesamt	*/
X	(compzuege<=50 ? compzuege:50):1));
X
X	sprintf(ret[zaehler++],"%d",stufe);		/* Spielstufe	*/
X
X	sprintf(ret[zaehler++],"%d",dat->minstufe);	/* Rechentiefen	*/
X	sprintf(ret[zaehler++],"%d",dat->maxstufe);
X
X	sprintf(ret[zaehler++],"%d",mode);		/* Modus	*/
X
X	if(!hole_zurueck(&datc,dat->zuege-1))		/* holen	*/
X	{
X		sprintf(ret[zaehler++],"%s",		/* letzter Zug	*/
X		wandle(_apos(dat->lzug),_npos(dat->lzug)));
X	}
X	else
X	{
X		WORD komb[2];				/* Kombination	*/
X
X		komb[0]=dat->lzug;			/* eintragen	*/
X		komb[1]=(WORD)0;			/* beenden	*/
X
X		sprintf(ret[zaehler++],"%s",		/* letzter Zug	*/
X		kombination(&datc,komb));		/* ausgeben	*/
X	}
}
X
/****************************************************************/
/*	Zugliste ausgeben					*/
/****************************************************************/
X
void	zugliste_aus(dat,modus,ret)
X
SPDAT	*dat;					/* Spieldaten	*/
int	modus;					/* 1: +Bew.	*/
char	*ret[];					/* Antworten	*/
{
X	int	i= -1;				/* Zaehler 	*/
X
X	while(dat->zlist[++i])			/* alle Zuege durch	*/
X	if(modus)				/* mit Bewertung	*/
X		sprintf(ret[zaehler++],"%s = %ld",
X		wandle(_apos(dat->zlist[i]),_npos(dat->zlist[i])),
X		dat->blist[i]);
X						/* kopieren	*/
X	else					/* ohne Bewertung	*/
X		sprintf(ret[zaehler++],"%s",
X		wandle(_apos(dat->zlist[i]),_npos(dat->zlist[i])));
X						/* kopieren	*/
X
X	sprintf(ret[zaehler++],"(%d)",i);
}
X
/****************************************************************/
/*	Zug/Positionsangabe umwandeln				*/
/****************************************************************/
/*	Falls posa == 0 : Positionsstring			*/
/****************************************************************/
X
char *wandle(posa,posn)
X
BYTE	posa,posn;				/* Positionen		*/
{
X	static 	char 	str[STRLEN];		/* String mit Pos/Zug 	*/
X	BYTE    	xposa,yposa;		/* Koordinaten	alt 	*/
X	BYTE    	xposn,yposn;		/* Koordinaten	neu 	*/
X
X	if(posa==(BYTE)0 && posn==(BYTE)0)	/* Kein Zug ?		*/
X		return("----");
X
X	xposa=_xpos(posa);			/* alte Koordinaten holen */
X	yposa=_ypos(posa);
X
X	if(posn!=(BYTE)0)
X	{
X		xposn=_xpos(posn);		/* neue Koordinaten holen */
X		yposn=_ypos(posn);
X
X		sprintf(str,"%c%c%c%c",		/* aufbereiten	*/
X		xposa+'a',yposa+'1',
X		xposn+'a',yposn+'1');
X	}
X	else
X		sprintf(str,"%c%c",		/* aufbereiten	*/
X		xposa+'a',yposa+'1');
X
X	return(str);
}
X
/****************************************************************/
/*	Zug/Positionsangabe inveres umwandeln			*/
/****************************************************************/
/*	Return: Zug/Position oder 0 bei Fehler			*/
/****************************************************************/
X
WORD wandle_inv(str)
X
char 	*str;				/* String mit Zug/Position	*/
{
X	WORD	zug=0;			/* Zug/Position	*/
X	int 	i,j;			/* Zaehler	*/
X	char	c;			/* aktuelles Zeichen in str	*/
X	WORD	teil[4];		/* Teile des Zugs	*/
X
X	for(i=0,j=0;str[i] != 0;i++)	/* String durchgehen		*/
X	{
X		c=str[i];
X
X		if(c==' ' || c=='-' || c=='x' || c=='_' || c=='+')
X			continue;
X		else switch(j)
X		{
X		case 0:
X		case 2:
X			if(c>='a' && c<='h')
X				teil[j++] = c-'a';
X			else if(c>='A' && c<='H')
X				teil[j++] = c-'A';
X			else
X				return((WORD)0);	/* Fehler	*/
X			break;
X
X		case 1:
X		case 3:
X			if(c>='1' && c<='8')
X				teil[j++] = c-'1';
X			else
X				return((WORD)0);	/* Fehler	*/
X			break;
X
X		default:
X			return((WORD)0);	/* Fehler	*/
X		}
X	}
X
X	if(j==2 || j==4)			/* korrekt ?	*/
X		zug |= teil[0]+RAND+(8+2*RAND)*(RAND+teil[1]);
X
X	if(j==4)				/* korrekt ?	*/
X		zug |= (teil[2]+RAND+(8+2*RAND)*(RAND+teil[3])) << 8;
X
X	return(zug);
}
X
/****************************************************************/
/*	Figur in internes Format				*/
/****************************************************************/
/*	Return: Figur oder 0 bei Fehler 			*/
/****************************************************************/
X
BYTE wandle_fig(c)
X
char c;					/* Figur	*/
{
X	char c2;
X	BYTE fig;			/* internes Format	*/
X
X	c2=c;
X	if(isupper(c))        		/* klein machen	*/
X		c2=tolower(c);
X
X	switch(c2)			/* umwandeln	*/
X	{
X	case 'b':
X		fig=BAU;
X		break;
X
X	case 's':
X		fig=SPR;
X		break;
X
X	case 'l':
X		fig=LAE;
X		break;
X
X	case 't':
X		fig=TUR;
X		break;
X
X	case 'd':
X		fig=DAM;
X		break;
X
X	case 'k':
X		fig=KOE;
X		break;
X
X	case '.':
X		fig=LEE;
X		break;
X
X	default:
X 		return(0);			/* Fehler	*/
X	}
X
X	if(isupper(c))
X		fig|=SCH;
X	else
X		fig|=WEI;
X
X	return(fig);
}
X
/****************************************************************/
/*	Kombination erstellen					*/
/****************************************************************/
/*	Return:	Kombinationsstring				*/
/****************************************************************/
X
char *kombination(dat,zugkomb)
X
SPDAT 	*dat;					/* Spieldaten		*/
WORD	zugkomb[];				/* Zugkombination 	*/
{
X	SPDAT		copy;			/* Kopie der Spieldaten	*/
X	SPDAT		*cdat;			/* Zeiger auf Kopie	*/
X	WORD		zug;
X	static char	str[STRLEN];		/* String		*/
X	int		i;
X
X	str[0]=0;				/* loeschen		*/
X
X	cdat= &copy;				/* Zeiger bestimmen	*/
X
X	if(dat == (SPDAT *)0)
X		init(cdat,1);
X	else
X	{
X		for(i=0;i<GROE;i++)		/* kopieren		*/
X			cdat->brett[i]=dat->brett[i];
X
X		cdat->wkpos	= dat->wkpos;
X		cdat->skpos	= dat->skpos;
X		cdat->farbe	= dat->farbe;
X		cdat->lzug      = dat->lzug;
X		cdat->zuege	= dat->zuege;
X	}
X
X	i=0;
X	while((zug=zugkomb[i])!=(WORD)0 && i<MAXTIEFE)	
X						/* Ende ?		*/
X	{
X		cdat->minstufe=spdat.minstufe;	/* damit Koenigsbedro.	*/
X		cdat->maxstufe=spdat.maxstufe;	/* ueberprueft wird	*/
X
X		if(!zug_test(cdat,zugkomb[i]))	/* illegaler Zug ?	*/
X			break;
X
X		sprintf(str+strlen(str),"%s%c",	/* String aufbereiten	*/
X		wandle(_apos(zug),(BYTE)0),
X		_istlee(cdat->brett[_npos(zug)]) ? '-':'x');
X
X		sprintf(str+strlen(str),"%s",
X		wandle(_npos(zug),(BYTE)0));
X
X		ziehe(cdat,zugkomb[i++]);	/* ziehen		*/
X
X		if(cdat->farbe==WEI)
X			if(bedrohung(cdat,cdat->wkpos))
X				strcat(str,"+");/* wei. Koenig bedroht	*/
X
X		if(cdat->farbe==SCH)
X			if(bedrohung(cdat,cdat->skpos))
X				strcat(str,"+");/* schw. Koenig bedroht	*/
X
X		strcat(str," ");		/* Trennzeichen		*/
X	}
X
X	str[strlen(str)-1]=0;			/* beenden		*/
X
X	return(str);
}
SHAR_EOF
chmod 0644 ch/utility.c ||
echo 'restore of ch/utility.c failed'
Wc_c="`wc -c < 'ch/utility.c'`"
test 7922 -eq "$Wc_c" ||
	echo 'ch/utility.c: original size 7922, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= ch/threat.c ==============
if test -f 'ch/threat.c' -a X"$1" != X"-c"; then
	echo 'x - skipping ch/threat.c (File already exists)'
	rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting ch/threat.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'ch/threat.c' &&
/****************************************************************/
/*								*/
/*	XChess V2.7: Bedrohung testen				*/
/*								*/
/*	(c) 1991 by Marc Laukien				*/
/*								*/
/****************************************************************/
X
#include "ch.h"			/* Def. des Schachspiels */
X
/****************************************************************/
/*	Feld auf Bedrohung testen				*/
/*	Testet nicht auf e.p.					*/
/****************************************************************/
/*	Return:	1: bedroht	0: nicht bedroht		*/
/****************************************************************/
X
int	bedrohung(dat,pos)
X
SPDAT	*dat;				/* Spieldaten	*/
BYTE	pos;				/* Position	*/
{
X	static short wbed[][12] =	/* Bedrohung durch Weiss	*/
X	{
X		/* Bedrohung durch Bauer */
X		{-11,-13,0},
X		/* Bedrohung durch Springer	*/
X		{14,25,23,10,-14,-25,-23,-10,0},
X		/* Bedrohung durch Laeufer Dame und Koenig	*/
X		{13,11,-13,-11,0},
X		/* Bedrohung durch Turm, Dame und Koenig	*/
X		{1,12,-1,-12,0},
X	};
X
X	static short sbed[][12] =	/* Bedrohung durch Schwarz	*/
X	{
X		/* Bedrohung durch Bauer */
X		{11,13,0},
X		/* Bedrohung durch Springer	*/
X		{14,25,23,10,-14,-25,-23,-10,0},
X		/* Bedrohung durch Laeufer Dame und Koenig	*/
X		{13,11,-13,-11,0},
X		/* Bedrohung durch Turm, Dame und Koenig	*/
X		{1,12,-1,-12,0},
X	};
X
X	register short	(*bed)[12];	/* effektive Bedrohungsliste	*/
X	register BYTE	k;		/* Zaehler			*/
X	register BYTE	pos2;		/* Position des Bedrohers	*/
X	register short	zug;		/* aktueller Zug		*/
X	register BYTE	fa;		/* Farbe			*/
X
X	if(_istlee(dat->brett[pos]))   	/* Farbe bestimmen	*/
X		fa=dat->farbe;
X	else
X		fa=_farbe(dat->brett[pos]);
X
X	if(fa==WEI)			/* eff. Bedrl. best.*/
X		bed=sbed;
X	else
X		bed=wbed;
X
X	for(k=0;zug=bed[2][k];k++)	/* LAEUFER, DAME, KOENIG	*/
X					/* alle Zuege durchg.		*/
X	{
X		pos2=(BYTE)((short)pos+zug);
X
X		if(_istkoe(dat->brett[pos2]) && fa!=_farbe(dat->brett[pos2]))
X			return(1);	/* Bedrohung gefunden	*/
X
X		while(_istlee(dat->brett[pos2]))	/* suchen	*/
X			pos2= (BYTE)((short)pos2+zug);
X
X		if((_istlae(dat->brett[pos2]) ||
X		    _istdam(dat->brett[pos2])) &&
X		     fa!=_farbe(dat->brett[pos2]))
X				return(1);	/* Bedrohung gefunden	*/
X	}
X
X	for(k=0;zug=bed[3][k];k++)	/* TURM, DAME, KOENIG	*/
X					/* alle Zuege durchg.	*/
X	{
X		pos2=(BYTE)((short)pos+zug);
X
X		if(_istkoe(dat->brett[pos2]) && fa!=_farbe(dat->brett[pos2]))
X			return(1);	/* Bedrohung gefunden	*/
X
X		while(_istlee(dat->brett[pos2]))	/* suchen	*/
X			pos2= (BYTE)((short)pos2+zug);
X
X		if((_isttur(dat->brett[pos2]) ||
X		    _istdam(dat->brett[pos2])) &&
X		     fa!=_farbe(dat->brett[pos2]))
X				return(1);	/* Bedrohung gefunden	*/
X	}
X
X	for(k=0;zug=bed[0][k];k++)	/* BAUER		*/
X					/* alle Zuege durchg.	*/
X	{
X		pos2=(BYTE)((short)pos+zug);
X		if(_istbau(dat->brett[pos2]) && fa!=_farbe(dat->brett[pos2]))
X			return(1);	/* Bedrohung gefunden	*/
X	}
X
X	for(k=0;zug=bed[1][k];k++)	/* SPRINGER		*/
X					/* alle Zuege durchg.	*/
X	{
X		pos2=(BYTE)((short)pos+zug);
X		if(_istspr(dat->brett[pos2]) && fa!=_farbe(dat->brett[pos2]))
X			return(1);	/* Bedrohung gefunden	*/
X	}
X
X	return(0);			/* keine Bedrohung gefunden	*/
}
SHAR_EOF
chmod 0644 ch/threat.c ||
echo 'restore of ch/threat.c failed'
Wc_c="`wc -c < 'ch/threat.c'`"
test 3106 -eq "$Wc_c" ||
	echo 'ch/threat.c: original size 3106, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= ch/init.c ==============
if test -f 'ch/init.c' -a X"$1" != X"-c"; then
	echo 'x - skipping ch/init.c (File already exists)'
	rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting ch/init.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'ch/init.c' &&
/****************************************************************/
/*								*/
/*	XChess V2.7: Initialisierungen				*/
/*								*/
/*	(c) 1991 by Marc Laukien				*/
/*								*/
/****************************************************************/
X
#include "ch.h"			/* Def. des Schachspiels */
#include <string.h>
#include <stdio.h>      	/* Standart IO */
X
extern	long	time();
extern	void	exit();
extern	char	*malloc();
extern	char	*memcpy();
extern	void	free();
extern	void	srand();
X
/****************************************************************/
/*	Initialisierungen					*/
/****************************************************************/
X
void	init(dat,modus)
X
SPDAT 	*dat;		/* Spieldaten	*/
int	modus;		/* 1=initialisieren, sonst nur loeschen	*/
{
X	static 	first=1;
X	BYTE	i,j;		/* Zaehler 	*/
X
X	static BYTE initbrett[8][8] =
X	{
XXTUR+WEI,SPR +WEI,LAE +WEI,DAM +WEI,XKOE+WEI,LAE +WEI,SPR +WEI,XTUR+WEI,
XXBAU+WEI,XBAU+WEI,XBAU+WEI,XBAU+WEI,XBAU+WEI,XBAU+WEI,XBAU+WEI,XBAU+WEI,
LEE     ,LEE     ,LEE     ,LEE     ,LEE     ,LEE     ,LEE     ,LEE     ,
LEE     ,LEE     ,LEE     ,LEE     ,LEE     ,LEE     ,LEE     ,LEE     ,
LEE     ,LEE     ,LEE     ,LEE     ,LEE     ,LEE     ,LEE     ,LEE     ,
LEE     ,LEE     ,LEE     ,LEE     ,LEE     ,LEE     ,LEE     ,LEE     ,
XXBAU+SCH,XBAU+SCH,XBAU+SCH,XBAU+SCH,XBAU+SCH,XBAU+SCH,XBAU+SCH,XBAU+SCH,
XXTUR+SCH,SPR +SCH,LAE +SCH,DAM +SCH,XKOE+SCH,LAE +SCH,SPR +SCH,XTUR+SCH,
X	};
X
X	if(first)		/* nur einmal ausfuehren	*/
X	{
X		srand((unsigned)time((long *)0));
X					/* Zufallsgenerator	*/
X		for(i=0;i<MAXSP;i++)	/* loeschen		*/
X			archiv[i]=(ARCHIV *)0;
X
X		load_open();		/* Eroeffnungen laden	*/
X		first=0;
X	}
X
X	for(i=0;i<GROE;i++)	/* Brett mit Spezialfiguren besetzen */
X		dat->brett[i]=SPZ;
X
X	if(modus==1)			/* Initialisieren ?	*/
X	{
X		for(j=0;j<8;j++)		/* aufbauen	*/
X			for(i=0;i<8;i++)
X				dat->brett[(j+RAND)*(8+2*RAND)+i+RAND]=
X				initbrett[j][i];
X
X		dat->wkpos=2*ZLEN+RAND+4;	/* Koenigspsoitionen	*/
X		dat->skpos=(2+7)*ZLEN+RAND+4;
X	}
X	else					/* Brett loeschen	*/
X	{
X		for(j=0;j<8;j++)
X			for(i=0;i<8;i++)
X				dat->brett[(j+RAND)*(8+2*RAND)+i+RAND]=LEE;
X
X		noop=0;		/* Bib. schliessen	*/
X
X		dat->wkpos=(BYTE)0;	/* Koenigspsoitionen	*/
X		dat->skpos=(BYTE)0;
X	}
X
X	dat->farbe 	=WEI;			/* Weiss beginnt	*/
X	dat->lzug  	=(WORD)0;		/* letzter Zug		*/
X	dat->zuege	=0;			/* Kein Zug bis jetzt	*/
X	dat->wert	=bewerte(dat,(BYTE)0);	/* Bewerten		*/
X	dat->vorher	=(SPDAT *)0;		/* kein Datensatz davor	*/
X
X	if(dat==&spdat)
X	{
X		varprosek=0L;			/* Varianten pro Sekunde*/
X		varianten=0L;			/* Varianten gesamt	*/
X		zeit=0L;			/* Rechenzeit		*/
X		compzuege=0;			/* Computerzuege	*/
X		noop=OPTRYS;			/* Eroeffnungen zulassen*/
X
X		for(i=0;i<MAXSP;i++)		/* Speicher freigeben	*/
X			if(archiv[i]!=(ARCHIV *)0)
X			{
X				free(archiv[i]);
X				archiv[i]=(ARCHIV *)0;
X			}
X
X		archiviere(&spdat);		/* archivieren 		*/
X	}
}
X
/************************************************************************/
/*      Eroeffnungen laden                                              */
/************************************************************************/
X
void	load_open()
X
{
X	FILE 	*fp;          		/* Filepointer 		*/
X	char 	str[200*5];             /* String zum einlesen	*/
X	char	str2[5];		/* String mit einem Zug	*/
X	WORD	open[200];		/* Array mit Eroeffnung	*/
X	BYTE	farbe;	/* Farbe fuer die die Eroeffnung gilt	*/
X	int i,j;
X
X	if((fp=fopen("chess.op","r"))==(FILE *)0)         /* oeffnen	*/
X		exit(1);                                /* Fehler 	*/
X
X	opnr=0;                         /* noch keine Eroeffnung 	*/
X
X	while(feof(fp)==0 && opnr < MAXOP)		/* Ende ?	*/
X        {
X		fgets(str,999,fp);      /* einlesen 	*/
X
X                i=0;
X		while(str[i]!='#' && str[i]!='\n' && str[i]!=0)
X			i++;
X
X		str[i]=0;               /* beenden 	*/
X
X		if(!strlen(str))	/* Leerzeile  ?	*/
X			continue;
X
X		farbe=(BYTE)0;
X
X		i=0;j=0;
X		while(i<strlen(str))
X                {
X			if(str[i]==' ' || str[i]==TAB || str[i]==';'
X			|| str[i]==',' || str[i]=='.' || str[i]==':')
X			{
X				i++;
X				continue;
X			}
X
X			if(str[i]=='W')		/* Komb. fuer Weiss ?	*/
SHAR_EOF
true || echo 'restore of ch/init.c failed'
fi
echo 'End of UnixChess part 1'
echo 'File ch/init.c is continued in part 2'
echo 2 > _shar_seq_.tmp
exit 0
-- 
   /              |    -: Marc Laukien :-     |
  /__             |                           |   _  _           __
 /   \  /_  /  /  |   ml@brumuc.muc.sub.org   |  / \/ |   /  /  /
/____/ /   /__/   | sigma@salyko.doit.sub.org | /     |  /__/  /__