1 /*        $NetBSD: allow.c,v 1.9 2024/08/22 20:46:40 rillig Exp $     */
2 
3 /*
4  * Copyright (c) 1980, 1993
5  *        The Regents of the University of California.  All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. Neither the name of the University nor the names of its contributors
16  *    may be used to endorse or promote products derived from this software
17  *    without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29  * SUCH DAMAGE.
30  */
31 
32 #include <sys/cdefs.h>
33 #ifndef lint
34 #if 0
35 static char sccsid[] = "@(#)allow.c     8.1 (Berkeley) 5/31/93";
36 #else
37 __RCSID("$NetBSD: allow.c,v 1.9 2024/08/22 20:46:40 rillig Exp $");
38 #endif
39 #endif /* not lint */
40 
41 #include "back.h"
42 
43 int
movallow(struct move * mm)44 movallow(struct move *mm)
45 {
46           int     i, m, iold;
47 
48           if (mm->d0)
49                     mswap(mm);
50           m = (mm->D0 == mm->D1 ? 4 : 2);
51           for (i = 0; i < 4; i++)
52                     mm->p[i] = bar;
53           i = iold = 0;
54           while (i < m) {
55                     if (*offptr == 15)
56                               break;
57                     mm->h[i] = 0;
58                     if (board[bar]) {
59                               if (i == 1 || m == 4)
60                                         mm->g[i] = bar + cturn * mm->D1;
61                               else
62                                         mm->g[i] = bar + cturn * mm->D0;
63                               if (makmove(mm, i) != 0) {
64                                         if (mm->d0 || m == 4)
65                                                   break;
66                                         mswap(mm);
67                                         movback(mm, i);
68                                         if (i > iold)
69                                                   iold = i;
70                                         for (i = 0; i < 4; i++)
71                                                   mm->p[i] = bar;
72                                         i = 0;
73                               } else
74                                         i++;
75                               continue;
76                     }
77                     if ((mm->p[i] += cturn) == home) {
78                               if (i > iold)
79                                         iold = i;
80                               if (m == 2 && i) {
81                                         movback(mm, i);
82                                         mm->p[i--] = bar;
83                                         if (mm->p[i] != bar)
84                                                   continue;
85                                         else
86                                                   break;
87                               }
88                               if (mm->d0 || m == 4)
89                                         break;
90                               mswap(mm);
91                               movback(mm, i);
92                               for (i = 0; i < 4; i++)
93                                         mm->p[i] = bar;
94                               i = 0;
95                               continue;
96                     }
97                     if (i == 1 || m == 4)
98                               mm->g[i] = mm->p[i] + cturn * mm->D1;
99                     else
100                               mm->g[i] = mm->p[i] + cturn * mm->D0;
101                     if (mm->g[i] * cturn > home) {
102                               if (*offptr >= 0)
103                                         mm->g[i] = home;
104                               else
105                                         continue;
106                     }
107                     if (board[mm->p[i]] * cturn > 0 && makmove(mm, i) == 0)
108                               i++;
109           }
110           movback(mm, i);
111           return (iold > i ? iold : i);
112 }
113