Down and dirty quick EPD balance approximator

Discussion of chess software programming and technical issues.

Moderator: Ras

Dann Corbit
Posts: 12791
Joined: Wed Mar 08, 2006 8:57 pm
Location: Redmond, WA USA

Down and dirty quick EPD balance approximator

Post by Dann Corbit »

This code will do a quick slash at telling if an EPD position is approximately balanced. It would be nice if someone would make a better one.

Code: Select all

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <assert.h>

/*
 * Copyright (c) 1988 Regents of the University of California.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

/*
 * thread-safe version of strtok
 */
char           *strtok_r(char *s, const char *delim, char **lasts)
{
    const char     *spanp;
    int             c,
    sc;
    char           *tok;

    /* s may be NULL */
    assert(delim != NULL);
    assert(lasts != NULL);

    if (s == NULL && (s = *lasts) == NULL)
        return (NULL);

    /* Skip (span) leading delimiters (s += strspn(s, delim), sort of). */
cont:
    c = *s++;
    for (spanp = delim; (sc = *spanp++) != 0;) {
        if (c == sc)
            goto cont;
    }

    if (c == 0) {               /* no non-delimiter characters */
        *lasts = NULL;
        return (NULL);
    }
    tok = s - 1;

    /* Scan token (scan for delimiters: s += strcspn(s, delim), sort of).
     * Note that delim must have one NUL; we stop if we see that, too. */
    for (;;) {
        c = *s++;
        spanp = delim;
        do {
            if ((sc = *spanp++) == c) {
                if (c == 0)
                    s = NULL;
                else
                    s[-1] = 0;
                *lasts = s;
                return (tok);
            }
        }
        while (sc != 0);
    }
    /* NOTREACHED */
}

char            string[32767];
char            last_epd[32767];

char           *getsafe(char *buffer, int count)
{
    char           *result = buffer,
                             *np;
    if ((buffer == NULL) || (count < 1))
        result = NULL;
    else if (count == 1)
        *result = 0;
    else if ((result = fgets(buffer, count, stdin)) != NULL)
        if (np = strchr(buffer, '\n'))
            *np = 0;
    return result;
}


int main(void)
{
    while (getsafe(string, sizeof string))
    {
        char *finger = 0;
        char *chessmen;
        strcpy(last_epd, string);
        chessmen = strtok_r(string, " ", &finger);
        if (chessmen)
        {
            char *color = strtok_r(NULL, " ", &finger);
            if (color)
            {
                int pawns = 0;
                int minors = 0;
                int rooks = 0;
                int queens = 0;
                int wood_score = 0;
                while (*chessmen)
                {
                    switch (*chessmen)
                    {
                    case 'P':
                        pawns++;
                        break;
                    case 'p':
                        pawns--;
                        break;
                    case 'N':
                    case 'B':
                        minors++;
                        break;
                    case 'n':
                    case 'b':
                        minors--;
                        break;
                    case 'R':
                        rooks++;
                        break;
                    case 'r':
                        rooks--;
                        break;
                    case 'Q':
                        queens++;
                        break;
                    case 'q':
                        queens--;
                        break;
                    }
                    chessmen++;
                }
                wood_score = pawns * 111 + minors * 415 + rooks * 640 + queens * 1275;
                if (wood_score < -99 || wood_score > +99)
                    printf(">> ** IMBALANCED ** << [%d]:( %s )\n", wood_score, last_epd);
#ifdef _DEBUG                    
                else
                    printf("BALANCED:( %s )\n", last_epd);
#endif                    
            }
        }
    }
    return 0;
}