-/* $NetBSD: pickmove.c,v 1.16 2009/06/04 06:27:47 dholland Exp $ */
+/* $NetBSD: pickmove.c,v 1.20 2010/03/29 05:16:08 dholland Exp $ */
/*
* Copyright (c) 1994
#if 0
static char sccsid[] = "@(#)pickmove.c 8.2 (Berkeley) 5/3/95";
#else
-__RCSID("$NetBSD: pickmove.c,v 1.16 2009/06/04 06:27:47 dholland Exp $");
+__RCSID("$NetBSD: pickmove.c,v 1.20 2010/03/29 05:16:08 dholland Exp $");
#endif
#endif /* not lint */
#define BIT_CLR(a, b) ((a)[(b)/BITS_PER_INT] &= ~(1 << ((b) % BITS_PER_INT)))
#define BIT_TEST(a, b) ((a)[(b)/BITS_PER_INT] & (1 << ((b) % BITS_PER_INT)))
-struct combostr *hashcombos[FAREA]; /* hash list for finding duplicates */
-struct combostr *sortcombos; /* combos at higher levels */
-int combolen; /* number of combos in sortcombos */
-int nextcolor; /* color of next move */
-int elistcnt; /* count of struct elist allocated */
-int combocnt; /* count of struct combostr allocated */
-int forcemap[MAPSZ]; /* map for blocking <1,x> combos */
-int tmpmap[MAPSZ]; /* map for blocking <1,x> combos */
-int nforce; /* count of opponent <1,x> combos */
+static struct combostr *hashcombos[FAREA];/* hash list for finding duplicates */
+static struct combostr *sortcombos; /* combos at higher levels */
+static int combolen; /* number of combos in sortcombos */
+static int nextcolor; /* color of next move */
+static int elistcnt; /* count of struct elist allocated */
+static int combocnt; /* count of struct combostr allocated */
+static int forcemap[MAPSZ]; /* map for blocking <1,x> combos */
+static int tmpmap[MAPSZ]; /* map for blocking <1,x> combos */
+static int nforce; /* count of opponent <1,x> combos */
+
+static int better(const struct spotstr *, const struct spotstr *, int);
+static void scanframes(int);
+static void makecombo2(struct combostr *, struct spotstr *, int, int);
+static void addframes(int);
+static void makecombo(struct combostr *, struct spotstr *, int, int);
+static void appendcombo(struct combostr *, int);
+static void updatecombo(struct combostr *, int);
+static void makeempty(struct combostr *);
+static int checkframes(struct combostr *, struct combostr *, struct spotstr *,
+ int, struct overlap_info *);
+static int sortcombo(struct combostr **, struct combostr **, struct combostr *);
+static void printcombo(struct combostr *, char *, size_t);
int
pickmove(int us)
/*
* Return true if spot 'sp' is better than spot 'sp1' for color 'us'.
*/
-int
+static int
better(const struct spotstr *sp, const struct spotstr *sp1, int us)
{
int them, s, s1;
if (sp->s_wval != sp1->s_wval)
return (0);
-#ifdef SVR4
- return (rand() & 1);
-#else
return (random() & 1);
-#endif
}
-int curcolor; /* implicit parameter to makecombo() */
-int curlevel; /* implicit parameter to makecombo() */
+static int curcolor; /* implicit parameter to makecombo() */
+static int curlevel; /* implicit parameter to makecombo() */
/*
* Scan the sorted list of non-empty frames and
* update the minimum combo values for each empty spot.
* Also, try to combine frames to find more complex (chained) moves.
*/
-void
+static void
scanframes(int color)
{
struct combostr *cbp, *ecbp;
* Compute all level 2 combos of frames intersecting spot 'osp'
* within the frame 'ocbp' and combo value 's'.
*/
-void
+static void
makecombo2(struct combostr *ocbp, struct spotstr *osp, int off, int s)
{
struct spotstr *fsp;
int baseB, fcnt, emask, bmask, n;
union comboval ocb, fcb;
struct combostr **scbpp, *fcbp;
+ char tmp[128];
/* try to combine a new frame with those found so far */
ocb.s = s;
combocnt++;
if ((c == 1 && debug > 1) || debug > 3) {
- debuglog(fmtbuf, "%c c %d %d m %x %x o %d %d",
+ debuglog("%c c %d %d m %x %x o %d %d",
"bw"[curcolor],
ncbp->c_framecnt[0], ncbp->c_framecnt[1],
ncbp->c_emask[0], ncbp->c_emask[1],
ncbp->c_voff[0], ncbp->c_voff[1]);
- printcombo(ncbp, fmtbuf);
- debuglog("%s", fmtbuf);
+ printcombo(ncbp, tmp, sizeof(tmp));
+ debuglog("%s", tmp);
}
if (c > 1) {
/* record the empty spots that will complete this combo */
combocnt--;
}
#ifdef DEBUG
- if (c == 1 && debug > 1 || debug > 5) {
+ if ((c == 1 && debug > 1) || debug > 5) {
markcombo(ncbp);
bdisp();
whatsup(0);
* Scan the sorted list of frames and try to add a frame to
* combinations of 'level' number of frames.
*/
-void
+static void
addframes(int level)
{
struct combostr *cbp, *ecbp;
* Compute all level N combos of frames intersecting spot 'osp'
* within the frame 'ocbp' and combo value 's'.
*/
-void
+static void
makecombo(struct combostr *ocbp, struct spotstr *osp, int off, int s)
{
struct combostr *cbp, *ncbp;
int baseB, fcnt, emask, verts;
union comboval ocb;
struct overlap_info vertices[1];
+ char tmp[128];
+
+ /*
+ * XXX: when I made functions static gcc started warning about
+ * some members of vertices[0] maybe being used uninitialized.
+ * For now I'm just going to clear it rather than wade through
+ * the logic to find out whether gcc or the code is wrong. I
+ * wouldn't be surprised if it were the code though. - dholland
+ */
+ memset(vertices, 0, sizeof(vertices));
ocb.s = s;
baseB = ocb.c.a + ocb.c.b - 1;
ncbp->c_framecnt[0], ncbp->c_framecnt[1],
ncbp->c_emask[0], ncbp->c_emask[1],
ncbp->c_voff[0], ncbp->c_voff[1]);
- printcombo(ncbp, fmtbuf);
- debuglog("%s", fmtbuf);
+ printcombo(ncbp, tmp, sizeof(tmp));
+ debuglog("%s", tmp);
}
if (c > 1) {
/* record the empty spots that will complete this combo */
updatecombo(ncbp, curcolor);
}
#ifdef DEBUG
- if (c == 1 && debug > 1 || debug > 4) {
+ if ((c == 1 && debug > 1) || debug > 4) {
markcombo(ncbp);
bdisp();
whatsup(0);
}
#define MAXDEPTH 100
-struct elist einfo[MAXDEPTH];
-struct combostr *ecombo[MAXDEPTH]; /* separate from elist to save space */
+static struct elist einfo[MAXDEPTH];
+static struct combostr *ecombo[MAXDEPTH]; /* separate from elist to save space */
/*
* Add the combostr 'ocbp' to the empty spots list for each empty spot
* in 'ocbp' that will complete the combo.
*/
-void
+static void
makeempty(struct combostr *ocbp)
{
struct combostr *cbp, *tcbp, **cbpp;
struct spotstr *sp;
int s, d, m, emask, i;
int nframes;
+ char tmp[128];
if (debug > 2) {
- printcombo(ocbp, fmtbuf);
- debuglog("E%c %s", "bw"[curcolor], fmtbuf);
+ printcombo(ocbp, tmp, sizeof(tmp));
+ debuglog("E%c %s", "bw"[curcolor], tmp);
}
/* should never happen but check anyway */
* We handle things differently depending on whether the next move
* would be trying to "complete" the combo or trying to block it.
*/
-void
+static void
updatecombo(struct combostr *cbp, int color)
{
struct spotstr *sp;
/*
* Add combo to the end of the list.
*/
-void
+static void
appendcombo(struct combostr *cbp, int color __unused)
{
struct combostr *pcbp, *ncbp;
* Return -1 if 'fcbp' should not be combined with 'cbp'.
* 's' is the combo value for frame 'fcpb'.
*/
-int
+static int
checkframes(struct combostr *cbp, struct combostr *fcbp, struct spotstr *osp,
int s, struct overlap_info *vertices)
{
* Return true if this list of frames is already in the hash list.
* Otherwise, add the new combo to the hash list.
*/
-int
+static int
sortcombo(struct combostr **scbpp, struct combostr **cbpp,
struct combostr *fcbp)
{
#ifdef DEBUG
if (debug > 3) {
- char *str;
+ char buf[128];
+ size_t pos;
debuglog("sortc: %s%c l%d", stoc(fcbp->c_vertex),
pdir[fcbp->c_dir], curlevel);
- str = fmtbuf;
+ pos = 0;
for (cpp = cbpp; cpp < cbpp + curlevel; cpp++) {
- sprintf(str, " %s%c", stoc((*cpp)->c_vertex),
- pdir[(*cpp)->c_dir]);
- str += strlen(str);
+ snprintf(buf + pos, sizeof(buf) - pos, " %s%c",
+ stoc((*cpp)->c_vertex), pdir[(*cpp)->c_dir]);
+ pos += strlen(buf + pos);
}
- debuglog("%s", fmtbuf);
+ debuglog("%s", buf);
}
#endif /* DEBUG */
/* we found a match */
#ifdef DEBUG
if (debug > 3) {
- char *str;
+ char buf[128];
+ size_t pos;
debuglog("sort1: n%d", n);
- str = fmtbuf;
+ pos = 0;
for (cpp = scbpp; cpp < scbpp + n; cpp++) {
- sprintf(str, " %s%c", stoc((*cpp)->c_vertex),
+ snprintf(buf + pos, sizeof(buf) - pos, " %s%c",
+ stoc((*cpp)->c_vertex),
pdir[(*cpp)->c_dir]);
- str += strlen(str);
+ pos += strlen(buf + pos);
}
- debuglog("%s", fmtbuf);
- printcombo(cbp, fmtbuf);
- debuglog("%s", fmtbuf);
- str = fmtbuf;
+ debuglog("%s", buf);
+ printcombo(cbp, buf, sizeof(buf));
+ debuglog("%s", buf);
cbpp--;
+ pos = 0;
for (cpp = cbpp; cpp < cbpp + n; cpp++) {
- sprintf(str, " %s%c", stoc((*cpp)->c_vertex),
+ snprintf(buf + pos, sizeof(buf) - pos, " %s%c",
+ stoc((*cpp)->c_vertex),
pdir[(*cpp)->c_dir]);
- str += strlen(str);
+ pos += strlen(buf + pos);
}
- debuglog("%s", fmtbuf);
+ debuglog("%s", buf);
}
#endif /* DEBUG */
return (1);
}
/*
- * Print the combo into string 'str'.
+ * Print the combo into string buffer 'buf'.
*/
-void
-printcombo(struct combostr *cbp, char *str)
+static void
+printcombo(struct combostr *cbp, char *buf, size_t max)
{
struct combostr *tcbp;
+ size_t pos = 0;
+
+ snprintf(buf + pos, max - pos, "%x/%d",
+ cbp->c_combo.s, cbp->c_nframes);
+ pos += strlen(buf + pos);
- sprintf(str, "%x/%d", cbp->c_combo.s, cbp->c_nframes);
- str += strlen(str);
for (; (tcbp = cbp->c_link[1]) != NULL; cbp = cbp->c_link[0]) {
- sprintf(str, " %s%c%x", stoc(tcbp->c_vertex), pdir[tcbp->c_dir],
- cbp->c_flags);
- str += strlen(str);
+ snprintf(buf + pos, max - pos, " %s%c%x",
+ stoc(tcbp->c_vertex), pdir[tcbp->c_dir], cbp->c_flags);
+ pos += strlen(buf + pos);
}
- sprintf(str, " %s%c", stoc(cbp->c_vertex), pdir[cbp->c_dir]);
+ snprintf(buf + pos, max - pos, " %s%c",
+ stoc(cbp->c_vertex), pdir[cbp->c_dir]);
}
#ifdef DEBUG
markcombo(struct combostr *ocbp)
{
struct combostr *cbp, *tcbp, **cbpp;
- struct elist *ep, *nep, **epp;
+ struct elist *ep, *nep;
struct spotstr *sp;
int s, d, m, i;
int nframes;
- int r, n, flags, cmask, omask;
+ int cmask, omask;
/* should never happen but check anyway */
if ((nframes = ocbp->c_nframes) >= MAXDEPTH)
*/
ep = &einfo[nframes];
cbpp = &ecombo[nframes];
- for (cbp = ocbp; tcbp = cbp->c_link[1]; cbp = cbp->c_link[0]) {
+ for (cbp = ocbp; (tcbp = cbp->c_link[1]) != NULL; cbp = cbp->c_link[0]) {
ep--;
ep->e_combo = cbp;
*--cbpp = cbp->c_link[1];
struct combostr *tcbp;
int d, n, mask;
- for (; tcbp = cbp->c_link[1]; cbp = cbp->c_link[0]) {
+ for (; (tcbp = cbp->c_link[1]) != NULL; cbp = cbp->c_link[0]) {
clearcombo(tcbp, cbp->c_flags & C_OPEN_1);
open = cbp->c_flags & C_OPEN_0;
}