xref: /netbsd-src/games/backgammon/teachgammon/tutor.c (revision 9a69f12d338a2b183268948a71393b9f3ecd75d6)
1*9a69f12dSrillig /*	$NetBSD: tutor.c,v 1.13 2024/08/22 20:46:40 rillig Exp $	*/
2101657d1Scgd 
361f28255Scgd /*
4101657d1Scgd  * Copyright (c) 1980, 1993
5101657d1Scgd  *	The Regents of the University of California.  All rights reserved.
661f28255Scgd  *
761f28255Scgd  * Redistribution and use in source and binary forms, with or without
861f28255Scgd  * modification, are permitted provided that the following conditions
961f28255Scgd  * are met:
1061f28255Scgd  * 1. Redistributions of source code must retain the above copyright
1161f28255Scgd  *    notice, this list of conditions and the following disclaimer.
1261f28255Scgd  * 2. Redistributions in binary form must reproduce the above copyright
1361f28255Scgd  *    notice, this list of conditions and the following disclaimer in the
1461f28255Scgd  *    documentation and/or other materials provided with the distribution.
15e5aeb4eaSagc  * 3. Neither the name of the University nor the names of its contributors
1661f28255Scgd  *    may be used to endorse or promote products derived from this software
1761f28255Scgd  *    without specific prior written permission.
1861f28255Scgd  *
1961f28255Scgd  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2061f28255Scgd  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2161f28255Scgd  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2261f28255Scgd  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2361f28255Scgd  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2461f28255Scgd  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2561f28255Scgd  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2661f28255Scgd  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2761f28255Scgd  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2861f28255Scgd  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2961f28255Scgd  * SUCH DAMAGE.
3061f28255Scgd  */
3161f28255Scgd 
3216641b76Slukem #include <sys/cdefs.h>
3361f28255Scgd #ifndef lint
34101657d1Scgd #if 0
35101657d1Scgd static char sccsid[] = "@(#)tutor.c	8.1 (Berkeley) 5/31/93";
36101657d1Scgd #else
37*9a69f12dSrillig __RCSID("$NetBSD: tutor.c,v 1.13 2024/08/22 20:46:40 rillig Exp $");
38101657d1Scgd #endif
3961f28255Scgd #endif				/* not lint */
4061f28255Scgd 
4161f28255Scgd #include "back.h"
4261f28255Scgd #include "tutor.h"
4361f28255Scgd 
44fcb317eeSjmc static const char better[] =
45fcb317eeSjmc 	"That is a legal move, but there is a better one.\n";
4661f28255Scgd 
479795f61aSdholland static int brdeq(const int *, const int *);
489795f61aSdholland static void clrest(void);
499795f61aSdholland 
5016641b76Slukem void
514105daf3Sdholland tutor(struct move *mm)
5216641b76Slukem {
5316641b76Slukem 	int     i, j;
5461f28255Scgd 
5561f28255Scgd 	i = 0;
5661f28255Scgd 	begscr = 18;
5761f28255Scgd 	cturn = -1;
5861f28255Scgd 	home = 0;
5961f28255Scgd 	bar = 25;
6061f28255Scgd 	inptr = &in[0];
6161f28255Scgd 	inopp = &in[1];
6261f28255Scgd 	offptr = &off[0];
6361f28255Scgd 	offopp = &off[1];
6461f28255Scgd 	Colorptr = &color[0];
6561f28255Scgd 	colorptr = &color[2];
6661f28255Scgd 	colen = 5;
6761f28255Scgd 	wrboard();
6861f28255Scgd 
69*9a69f12dSrillig 	for (;;) {
7061f28255Scgd 		if (!brdeq(test[i].brd, board)) {
7161f28255Scgd 			if (tflag && curr == 23)
7261f28255Scgd 				curmove(18, 0);
7361f28255Scgd 			writel(better);
7461f28255Scgd 			nexturn();
754105daf3Sdholland 			movback(mm, mm->mvlim);
7661f28255Scgd 			if (tflag) {
7761f28255Scgd 				refresh();
7861f28255Scgd 				clrest();
7961f28255Scgd 			}
8061f28255Scgd 			if ((!tflag) || curr == 19) {
814105daf3Sdholland 				proll(mm);
8261f28255Scgd 				writec('\t');
8316641b76Slukem 			} else
8461f28255Scgd 				curmove(curr > 19 ? curr - 2 : curr + 4, 25);
854105daf3Sdholland 			getmove(mm);
8661f28255Scgd 			if (cturn == 0)
8761f28255Scgd 				leave();
8861f28255Scgd 			continue;
8961f28255Scgd 		}
9061f28255Scgd 		if (tflag)
9161f28255Scgd 			curmove(18, 0);
925f0f7c9fSmrg 		wrtext(*test[i].com);
9361f28255Scgd 		if (!tflag)
9461f28255Scgd 			writec('\n');
9561f28255Scgd 		if (i == maxmoves)
9661f28255Scgd 			break;
978733c61fSdholland 		mm->D0 = test[i].roll1;
988733c61fSdholland 		mm->D1 = test[i].roll2;
998733c61fSdholland 		mm->d0 = 0;
1008733c61fSdholland 		mm->mvlim = 0;
10161f28255Scgd 		for (j = 0; j < 4; j++) {
10261f28255Scgd 			if (test[i].mp[j] == test[i].mg[j])
10361f28255Scgd 				break;
1048733c61fSdholland 			mm->p[j] = test[i].mp[j];
1058733c61fSdholland 			mm->g[j] = test[i].mg[j];
1068733c61fSdholland 			mm->mvlim++;
10761f28255Scgd 		}
1088733c61fSdholland 		if (mm->mvlim)
1098733c61fSdholland 			for (j = 0; j < mm->mvlim; j++)
1104105daf3Sdholland 				if (makmove(mm, j))
11161f28255Scgd 					writel("AARGH!!!\n");
11261f28255Scgd 		if (tflag)
11361f28255Scgd 			refresh();
11461f28255Scgd 		nexturn();
1158733c61fSdholland 		mm->D0 = test[i].new1;
1168733c61fSdholland 		mm->D1 = test[i].new2;
1178733c61fSdholland 		mm->d0 = 0;
11861f28255Scgd 		i++;
1194105daf3Sdholland 		mm->mvlim = movallow(mm);
1208733c61fSdholland 		if (mm->mvlim) {
12161f28255Scgd 			if (tflag)
12261f28255Scgd 				clrest();
1234105daf3Sdholland 			proll(mm);
12461f28255Scgd 			writec('\t');
1254105daf3Sdholland 			getmove(mm);
12661f28255Scgd 			if (tflag)
12761f28255Scgd 				refresh();
12861f28255Scgd 			if (cturn == 0)
12961f28255Scgd 				leave();
13061f28255Scgd 		}
13161f28255Scgd 	}
13261f28255Scgd 	leave();
13361f28255Scgd }
13461f28255Scgd 
1359795f61aSdholland static void
136fcb317eeSjmc clrest(void)
13716641b76Slukem {
13816641b76Slukem 	int     r, c, j;
13961f28255Scgd 
14061f28255Scgd 	r = curr;
14161f28255Scgd 	c = curc;
14261f28255Scgd 	for (j = r + 1; j < 24; j++) {
14361f28255Scgd 		curmove(j, 0);
14461f28255Scgd 		cline();
14561f28255Scgd 	}
14661f28255Scgd 	curmove(r, c);
14761f28255Scgd }
14861f28255Scgd 
1499795f61aSdholland static int
150fcb317eeSjmc brdeq(const int *b1, const int *b2)
15161f28255Scgd {
15292932dfcShubertf 	const int    *e;
15361f28255Scgd 
15461f28255Scgd 	e = b1 + 26;
15561f28255Scgd 	while (b1 < e)
15661f28255Scgd 		if (*b1++ != *b2++)
15761f28255Scgd 			return (0);
15861f28255Scgd 	return (1);
15961f28255Scgd }
160