summaryrefslogtreecommitdiff
path: root/osr.c
diff options
context:
space:
mode:
authorRuss Allbery <rra@debian.org>2013-07-21 13:49:36 -0700
committerRuss Allbery <rra@debian.org>2013-07-21 13:49:36 -0700
commit02afa49ca106bbd29895a61ce16c110d3d819b3d (patch)
tree5b1c86964e47ed31dca8c4f96fa9b88c48f28e0a /osr.c
parent71a137c6c77cadddd4ed628cf0dcc310fbb32a49 (diff)
Imported Upstream version 1.01.003
Diffstat (limited to 'osr.c')
-rw-r--r--osr.c1041
1 files changed, 518 insertions, 523 deletions
diff --git a/osr.c b/osr.c
index 840dd23..ff8cf0a 100644
--- a/osr.c
+++ b/osr.c
@@ -20,10 +20,10 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
- * $Id: osr.c,v 1.34 2009/04/20 15:44:09 c_anthon Exp $
+ * $Id: osr.c,v 1.36 2013/07/10 20:51:46 mdpetch Exp $
*/
-/*lint -e514*/
+/*lint -e514 */
#include "config.h"
@@ -38,40 +38,44 @@
#define MAX_PROBS 32
#define MAX_GAMMON_PROBS 15
-static unsigned long mt[ N ];
+static unsigned long mt[N];
static int mti = N + 1;
-static unsigned int OSRQuasiRandomDice( const unsigned int iTurn, const unsigned int iGame, const unsigned int cGames, unsigned int anDice[ 2 ] )
+static unsigned int
+OSRQuasiRandomDice(const unsigned int iTurn, const unsigned int iGame, const unsigned int cGames,
+ unsigned int anDice[2])
{
- if( !iTurn && !( cGames % 36 ) ) {
- anDice[ 0 ] = ( iGame % 6 ) + 1;
- anDice[ 1 ] = ( ( iGame / 6 ) % 6 ) + 1;
- return TRUE;
- } else if( iTurn == 1 && !( cGames % 1296 ) ) {
- anDice[ 0 ] = ( ( iGame / 36 ) % 6 ) + 1;
- anDice[ 1 ] = ( ( iGame / 216 ) % 6 ) + 1;
- return TRUE;
- } else {
- anDice[ 0 ] = ( genrand_int32(&mti,mt) % 6 ) + 1;
- anDice[ 1 ] = ( genrand_int32(&mti,mt) % 6 ) + 1;
- return ( anDice[ 0 ] > 0 && anDice[ 1 ] > 0 );
- }
+ if (!iTurn && !(cGames % 36)) {
+ anDice[0] = (iGame % 6) + 1;
+ anDice[1] = ((iGame / 6) % 6) + 1;
+ return TRUE;
+ } else if (iTurn == 1 && !(cGames % 1296)) {
+ anDice[0] = ((iGame / 36) % 6) + 1;
+ anDice[1] = ((iGame / 216) % 6) + 1;
+ return TRUE;
+ } else {
+ anDice[0] = (genrand_int32(&mti, mt) % 6) + 1;
+ anDice[1] = (genrand_int32(&mti, mt) % 6) + 1;
+ return (anDice[0] > 0 && anDice[1] > 0);
+ }
}
/* Fill aaProb with one sided bearoff probabilities for position with */
/* bearoff id n. */
-static inline void getBearoffProbs(const unsigned int n, unsigned short int aaProb[32])
+static inline void
+getBearoffProbs(const unsigned int n, unsigned short int aaProb[32])
{
- g_assert( pbc1 );
- if (BearoffDist ( pbc1, n, NULL, NULL, NULL, aaProb, NULL ))
- puts("BearoffDist failed?");
+ g_assert(pbc1);
+ if (BearoffDist(pbc1, n, NULL, NULL, NULL, aaProb, NULL))
+ puts("BearoffDist failed?");
}
static int
-isCrossOver ( const unsigned int from, const unsigned int to ) {
- return ( from / 6 ) != ( to / 6 );
+isCrossOver(const unsigned int from, const unsigned int to)
+{
+ return (from / 6) != (to / 6);
}
@@ -89,222 +93,230 @@ isCrossOver ( const unsigned int from, const unsigned int to ) {
*
*/
-static unsigned int chequersout(const unsigned int anBoard[25])
+#if !defined(G_DISABLE_ASSERT)
+
+static unsigned int
+chequersout(const unsigned int anBoard[25])
{
- unsigned int i, n = 0;
+ unsigned int i, n = 0;
- for (i = 6; i < 25; i++)
- n += anBoard[i];
+ for (i = 6; i < 25; i++)
+ n += anBoard[i];
- return n;
+ return n;
}
+#endif
+
/*! \brief checks that we haven't moved too many checkers of any point on the board
* but board need not contain all 15 checkers */
-static int checkboard(const unsigned int anBoard[25])
+#if !defined(G_DISABLE_ASSERT)
+
+static int
+checkboard(const unsigned int anBoard[25])
{
- unsigned int i;
+ unsigned int i;
- for (i = 0; i < 25; i++)
- if (anBoard[i] > 15)
- return 0;
- return 1;
+ for (i = 0; i < 25; i++)
+ if (anBoard[i] > 15)
+ return 0;
+ return 1;
}
-static void FindBestMoveOSR2 ( unsigned int anBoard[ 25 ], const unsigned int anDice[ 2 ], unsigned int *pnOut )
+#endif
+
+static void
+FindBestMoveOSR2(unsigned int anBoard[25], const unsigned int anDice[2], unsigned int *pnOut)
{
- unsigned int ifar, inear, iboth;
- unsigned int iused = 0;
- unsigned int i, j, lc;
- unsigned int found;
+ unsigned int ifar, inear, iboth;
+ unsigned int iused = 0;
+ unsigned int i, j, lc;
+ unsigned int found;
- ifar = 5 + anDice[ 0 ];
- inear = 5 + anDice[ 1 ];
+ ifar = 5 + anDice[0];
+ inear = 5 + anDice[1];
- if ( anBoard[ ifar ] && anBoard[ inear ] ) {
+ if (anBoard[ifar] && anBoard[inear]) {
- /* two chequers move exactly into the home quadrant */
+ /* two chequers move exactly into the home quadrant */
- /* move chequers */
+ /* move chequers */
- --anBoard[ ifar ];
- --anBoard[ inear ];
- g_assert ( checkboard ( anBoard ) );
- anBoard[ 5 ] += 2;
+ --anBoard[ifar];
+ --anBoard[inear];
+ g_assert(checkboard(anBoard));
+ anBoard[5] += 2;
- g_assert(*pnOut >= 2);
- *pnOut -= 2;
- g_assert ( *pnOut == chequersout ( anBoard ) );
+ g_assert(*pnOut >= 2);
+ *pnOut -= 2;
+ g_assert(*pnOut == chequersout(anBoard));
- return;
- }
+ return;
+ }
- iboth = 5 + ( anDice[ 0 ] + anDice[ 1 ] );
+ iboth = 5 + (anDice[0] + anDice[1]);
- if ( anBoard[ iboth ] ) {
+ if (anBoard[iboth]) {
- /* one chequer move exactly into the home quadrant */
+ /* one chequer move exactly into the home quadrant */
- /* move chequer */
+ /* move chequer */
- --anBoard[ iboth ];
- ++anBoard[ 5 ];
- g_assert ( checkboard ( anBoard ) );
+ --anBoard[iboth];
+ ++anBoard[5];
+ g_assert(checkboard(anBoard));
- g_assert ( *pnOut > 0 );
- --*pnOut;
- g_assert ( *pnOut == chequersout ( anBoard ) );
+ g_assert(*pnOut > 0);
+ --*pnOut;
+ g_assert(*pnOut == chequersout(anBoard));
- return;
+ return;
- }
+ }
- /* loop through dice */
+ /* loop through dice */
- for ( i = 0; i < 2 && *pnOut; ++i ) {
+ for (i = 0; i < 2 && *pnOut; ++i) {
- /* check for exact cross over */
+ /* check for exact cross over */
- if ( anBoard[ 5 + anDice[ i ] ] ) {
+ if (anBoard[5 + anDice[i]]) {
- /* move chequer */
+ /* move chequer */
- --anBoard[ 5 + anDice[ i ] ];
- ++anBoard[ 5 ];
- g_assert ( checkboard ( anBoard ) );
+ --anBoard[5 + anDice[i]];
+ ++anBoard[5];
+ g_assert(checkboard(anBoard));
- g_assert ( *pnOut > 0 );
- --*pnOut;
- g_assert ( *pnOut == chequersout ( anBoard ) );
+ g_assert(*pnOut > 0);
+ --*pnOut;
+ g_assert(*pnOut == chequersout(anBoard));
- ++iused;
+ ++iused;
- /* next die */
+ /* next die */
- continue;
+ continue;
- }
+ }
- /* find chequer furthest away */
+ /* find chequer furthest away */
- lc = 24;
- while ( lc > 5 && ! anBoard[ lc ] )
- --lc;
+ lc = 24;
+ while (lc > 5 && !anBoard[lc])
+ --lc;
- /* try to make cross over from the back */
+ /* try to make cross over from the back */
- found = FALSE;
- for ( j = lc; j - anDice[ i ] > 5; --j ) {
+ found = FALSE;
+ for (j = lc; j - anDice[i] > 5; --j) {
- if ( anBoard[ j ] && isCrossOver ( j, j - anDice[ i ] ) ) {
+ if (anBoard[j] && isCrossOver(j, j - anDice[i])) {
- /* move chequer */
+ /* move chequer */
- --anBoard[ j ];
- ++anBoard[ j - anDice[ i ] ];
- g_assert ( checkboard ( anBoard ) );
- ++iused;
- found = TRUE;
- /* FIXME: increment lc if needed */
+ --anBoard[j];
+ ++anBoard[j - anDice[i]];
+ g_assert(checkboard(anBoard));
+ ++iused;
+ found = TRUE;
+ /* FIXME: increment lc if needed */
- break;
+ break;
- }
+ }
- }
+ }
- if ( ! found ) {
+ if (!found) {
- /* no move with cross-over was found */
+ /* no move with cross-over was found */
- /* move chequer from the rear */
+ /* move chequer from the rear */
- for ( j = lc; j > 5; --j ) {
+ for (j = lc; j > 5; --j) {
- if ( anBoard[ j ] ) {
+ if (anBoard[j]) {
- --anBoard[ j ];
- ++anBoard[ j - anDice[ i ] ];
- g_assert ( checkboard ( anBoard ) );
- ++iused;
+ --anBoard[j];
+ ++anBoard[j - anDice[i]];
+ g_assert(checkboard(anBoard));
+ ++iused;
- if ( j - anDice[ i ] < 6 )
- { /* we've moved inside home quadrant */
- g_assert ( *pnOut > 0 );
- --*pnOut;
- }
+ if (j - anDice[i] < 6) { /* we've moved inside home quadrant */
+ g_assert(*pnOut > 0);
+ --*pnOut;
+ }
+
+ g_assert(*pnOut == chequersout(anBoard));
- g_assert ( *pnOut == chequersout ( anBoard ) );
+ break;
+
+ }
+
+ }
- break;
}
-
- }
-
-
+
}
-
- }
- if ( ! *pnOut && iused < 2 ) {
+ if (!*pnOut && iused < 2) {
- /* die 2 still left, and all chequers inside home quadrant */
+ /* die 2 still left, and all chequers inside home quadrant */
- if ( anBoard[ anDice[ 1 ] - 1 ] ) {
- /* bear-off */
- --anBoard[ anDice[ 1 ] - 1 ];
- g_assert ( checkboard ( anBoard ) );
- return;
- }
+ if (anBoard[anDice[1] - 1]) {
+ /* bear-off */
+ --anBoard[anDice[1] - 1];
+ g_assert(checkboard(anBoard));
+ return;
+ }
- /* try filling rearest empty space */
-
- for (i = 0; i < 6 - anDice[ 1 ]; i++)
- {
- j = 5 - i;
- if ( anBoard[ j ] && ! anBoard[ j - anDice[ 1 ] ] ) {
- /* empty space found */
-
- --anBoard[ j ];
- ++anBoard[ j - anDice[ 1 ] ];
-
- g_assert ( checkboard ( anBoard ) );
- return;
-
- }
- }
+ /* try filling rearest empty space */
- /* move chequer from the rear */
- for (i = 0; i < 6; i++)
- {
- j = 5 - i;
+ for (i = 0; i < 6 - anDice[1]; i++) {
+ j = 5 - i;
+ if (anBoard[j] && !anBoard[j - anDice[1]]) {
+ /* empty space found */
- if ( anBoard[ j ] ) {
+ --anBoard[j];
+ ++anBoard[j - anDice[1]];
+
+ g_assert(checkboard(anBoard));
+ return;
+
+ }
+ }
/* move chequer from the rear */
+ for (i = 0; i < 6; i++) {
+ j = 5 - i;
- --anBoard[ j ];
+ if (anBoard[j]) {
- if ( j >= anDice[ 1 ] )
- /* add chequer to point */
- ++anBoard[ j - anDice[ 1 ] ];
- /* else */
- /* bearoff */
+ /* move chequer from the rear */
- g_assert ( checkboard ( anBoard ) );
- return;
+ --anBoard[j];
- }
+ if (j >= anDice[1])
+ /* add chequer to point */
+ ++anBoard[j - anDice[1]];
+ /* else */
+ /* bearoff */
- }
+ g_assert(checkboard(anBoard));
+ return;
+
+ }
- }
+ }
+
+ }
- g_assert ( iused == 2 );
- return;
+ g_assert(iused == 2);
+ return;
}
@@ -322,203 +334,191 @@ static void FindBestMoveOSR2 ( unsigned int anBoard[ 25 ], const unsigned int an
*
*/
-static void FindBestMoveOSR4(unsigned int anBoard[ 25 ], const unsigned int nDice, unsigned int *pnOut)
+static void
+FindBestMoveOSR4(unsigned int anBoard[25], const unsigned int nDice, unsigned int *pnOut)
{
- unsigned int nd = 4;
- unsigned int i, j, n = 0;
- unsigned int first, any;
- unsigned int lc;
+ unsigned int nd = 4;
+ unsigned int i, j, n = 0;
+ unsigned int first, any;
+ unsigned int lc;
- /* check for exact bear-ins */
+ /* check for exact bear-ins */
- while ( nd > 0 && *pnOut > 0 && anBoard[ 5 + nDice ] )
- {
- --anBoard[ 5 + nDice ];
- ++anBoard[ 5 ];
- g_assert ( checkboard ( anBoard ) );
+ while (nd > 0 && *pnOut > 0 && anBoard[5 + nDice]) {
+ --anBoard[5 + nDice];
+ ++anBoard[5];
+ g_assert(checkboard(anBoard));
- --nd;
- g_assert ( *pnOut > 0 );
- --*pnOut;
- g_assert ( *pnOut == chequersout ( anBoard ) );
+ --nd;
+ g_assert(*pnOut > 0);
+ --*pnOut;
+ g_assert(*pnOut == chequersout(anBoard));
- }
+ }
#if 0
- /* this is broken or very very slow when the player has chequers in the
- * 3rd or 4th quadrant */
- if (*pnOut > 0)
- {
- /* check for 4, 3, or 2 chequers move exactly into home quadrant */
-
- for ( n = nd; n > 1; --n ) {
-
- i = 5 + n * nDice;
-
- if ( i < 25 && anBoard[ i ] ) {
-
- --anBoard[ i ];
- ++anBoard[ 5 ];
- g_assert ( checkboard ( anBoard ) );
-
- nd -= n;
- g_assert (*pnOut > 0);
- --*pnOut;
- g_assert ( *pnOut == chequersout ( anBoard ) );
-
- n =nd; /* restart loop */
- }
+ /* this is broken or very very slow when the player has chequers in the
+ * 3rd or 4th quadrant */
+ if (*pnOut > 0) {
+ /* check for 4, 3, or 2 chequers move exactly into home quadrant */
+
+ for (n = nd; n > 1; --n) {
+
+ i = 5 + n * nDice;
+
+ if (i < 25 && anBoard[i]) {
+
+ --anBoard[i];
+ ++anBoard[5];
+ g_assert(checkboard(anBoard));
+
+ nd -= n;
+ g_assert(*pnOut > 0);
+ --*pnOut;
+ g_assert(*pnOut == chequersout(anBoard));
+
+ n = nd; /* restart loop */
+ }
+ }
}
- }
#endif
- if ( *pnOut > 0 && nd > 0 )
- {
- first = TRUE;
+ if (*pnOut > 0 && nd > 0) {
+ first = TRUE;
+
+ /* find rearest chequer */
+
+ lc = 24;
+ while (lc > 5 && !anBoard[lc])
+ --lc;
+
+ /* try to make cross over from the back */
+
+ for (i = lc; i > 5; --i) {
- /* find rearest chequer */
+ if (anBoard[i]) {
- lc = 24;
- while ( lc > 5 && ! anBoard[ lc ] )
- --lc;
+ if (isCrossOver(i, i - nDice) && (first || (i - nDice) > 5)) {
- /* try to make cross over from the back */
+ /* move chequers */
- for ( i = lc; i > 5; --i ) {
+ while (anBoard[i] && nd && *pnOut) {
+ --anBoard[i];
+ ++anBoard[i - nDice];
+ g_assert(checkboard(anBoard));
- if ( anBoard[ i ] ) {
+ if (i - nDice < 6) { /* we move into homeland */
+ g_assert(*pnOut > 0);
+ --*pnOut;
+ }
- if ( isCrossOver ( i, i - nDice ) && ( first || (i - nDice) > 5 ) ) {
- /* move chequers */
-
- while ( anBoard[ i ] && nd && *pnOut )
- {
- --anBoard[ i ];
- ++anBoard[ i - nDice ];
- g_assert ( checkboard ( anBoard ) );
-
- if ( i - nDice < 6 )
- { /* we move into homeland */
- g_assert ( *pnOut > 0 );
- --*pnOut;
- }
+ g_assert(*pnOut == chequersout(anBoard));
-
- g_assert ( *pnOut == chequersout ( anBoard ) );
-
- --nd;
- }
+ --nd;
+ }
- if ( ! *pnOut || ! nd )
- break;
+ if (!*pnOut || !nd)
+ break;
- /* did we move all chequers from that point */
+ /* did we move all chequers from that point */
- first = ! anBoard[ i ];
+ first = !anBoard[i];
+ }
+ }
}
- }
- }
- /* move chequers from the rear */
-
- while ( *pnOut && nd )
- {
- for ( i = lc; i > 5; --i )
- {
- if( anBoard[ i ] )
- {
- while ( anBoard[ i ] && nd && *pnOut )
- {
- --anBoard[ i ];
- ++anBoard[ i - nDice ];
- g_assert ( checkboard ( anBoard ) );
-
- if ( i - nDice < 6 )
- {
- g_assert ( *pnOut > 0 );
- --*pnOut;
- }
-
- g_assert ( *pnOut == chequersout ( anBoard ) );
-
- --nd;
- }
-
- if ( ! n || ! *pnOut )
- break;
+ /* move chequers from the rear */
+
+ while (*pnOut && nd) {
+ for (i = lc; i > 5; --i) {
+ if (anBoard[i]) {
+ while (anBoard[i] && nd && *pnOut) {
+ --anBoard[i];
+ ++anBoard[i - nDice];
+ g_assert(checkboard(anBoard));
+
+ if (i - nDice < 6) {
+ g_assert(*pnOut > 0);
+ --*pnOut;
+ }
+
+ g_assert(*pnOut == chequersout(anBoard));
+
+ --nd;
+ }
+
+ if (!n || !*pnOut)
+ break;
+ }
+ }
}
- }
}
- }
-
- if (!*pnOut )
- { /* all chequers inside home quadrant */
- while ( nd )
- {
- if ( anBoard[ nDice - 1 ] ) {
- /* perfect bear-off */
- --anBoard[ nDice - 1 ];
- --nd;
- g_assert ( checkboard ( anBoard ) );
- continue;
- }
- if ( nd >= 2 && nDice <= 3 && anBoard[ 2 *nDice - 1 ] > 0 ) {
- /* bear double 1s, 2s, and 3s off, e.g., 4/2/0 */
- --anBoard[ 2 * nDice - 1 ];
- nd -= 2;
- g_assert ( checkboard ( anBoard ) );
- continue;
- }
+ if (!*pnOut) { /* all chequers inside home quadrant */
+ while (nd) {
+ if (anBoard[nDice - 1]) {
+ /* perfect bear-off */
+ --anBoard[nDice - 1];
+ --nd;
+ g_assert(checkboard(anBoard));
+ continue;
+ }
- if ( nd >= 3 && nDice <= 2 && anBoard[ 3 * nDice - 1 ] > 0 ) {
- /* bear double 1s off from 3 point (3/2/1/0) or
- double 2s off from 6 point (6/4/2/0) */
- --anBoard[ 3 * nDice - 1 ];
- nd -= 3;
- g_assert ( checkboard ( anBoard ) );
- continue;
- }
+ if (nd >= 2 && nDice <= 3 && anBoard[2 * nDice - 1] > 0) {
+ /* bear double 1s, 2s, and 3s off, e.g., 4/2/0 */
+ --anBoard[2 * nDice - 1];
+ nd -= 2;
+ g_assert(checkboard(anBoard));
+ continue;
+ }
- if ( nd >= 4 && nDice <= 1 && anBoard[ 4 * nDice - 1] > 0 ) {
- /* hmmm, this should not be possible... */
- /* bear off double 1s: 4/3/2/1/0 */
- --anBoard[ 4 * nDice - 1 ];
- g_assert ( checkboard ( anBoard ) );
- nd -= 4;
- }
+ if (nd >= 3 && nDice <= 2 && anBoard[3 * nDice - 1] > 0) {
+ /* bear double 1s off from 3 point (3/2/1/0) or
+ * double 2s off from 6 point (6/4/2/0) */
+ --anBoard[3 * nDice - 1];
+ nd -= 3;
+ g_assert(checkboard(anBoard));
+ continue;
+ }
- any = FALSE;
+ if (nd >= 4 && nDice <= 1 && anBoard[4 * nDice - 1] > 0) {
+ /* hmmm, this should not be possible... */
+ /* bear off double 1s: 4/3/2/1/0 */
+ --anBoard[4 * nDice - 1];
+ g_assert(checkboard(anBoard));
+ nd -= 4;
+ }
- /* move chequers from rear */
+ any = FALSE;
- /* FIXME: fill gaps? */
+ /* move chequers from rear */
- for (i = 0; nd && i < 6; i++)
- {
- j = 5 - i;
+ /* FIXME: fill gaps? */
- while ( anBoard[ j ] && nd ) {
+ for (i = 0; nd && i < 6; i++) {
+ j = 5 - i;
- any = TRUE;
+ while (anBoard[j] && nd) {
- --anBoard[ j ];
- --nd;
+ any = TRUE;
- if ( j >= nDice )
- ++anBoard[ j - nDice ];
- g_assert ( checkboard ( anBoard ) );
+ --anBoard[j];
+ --nd;
- }
+ if (j >= nDice)
+ ++anBoard[j - nDice];
+ g_assert(checkboard(anBoard));
- }
+ }
- if ( ! any )
- /* no more chequers left */
- nd = 0;
+ }
+
+ if (!any)
+ /* no more chequers left */
+ nd = 0;
+ }
}
- }
}
@@ -536,12 +536,13 @@ static void FindBestMoveOSR4(unsigned int anBoard[ 25 ], const unsigned int nDic
*
*/
-static void FindBestMoveOSR(unsigned int anBoard[ 25 ], const unsigned int anDice[ 2 ], unsigned int *pnOut)
+static void
+FindBestMoveOSR(unsigned int anBoard[25], const unsigned int anDice[2], unsigned int *pnOut)
{
- if (anDice[0] != anDice[1])
- FindBestMoveOSR2(anBoard, anDice, pnOut);
- else
- FindBestMoveOSR4(anBoard, anDice[0], pnOut);
+ if (anDice[0] != anDice[1])
+ FindBestMoveOSR2(anBoard, anDice, pnOut);
+ else
+ FindBestMoveOSR4(anBoard, anDice[0], pnOut);
}
/*
@@ -557,29 +558,29 @@ static void FindBestMoveOSR(unsigned int anBoard[ 25 ], const unsigned int anDic
* quadrant.
*/
-static unsigned int osr(unsigned int anBoard[25], const unsigned int iGame, const unsigned int nGames, unsigned int nOut)
+static unsigned int
+osr(unsigned int anBoard[25], const unsigned int iGame, const unsigned int nGames, unsigned int nOut)
{
- unsigned int iTurn = 0;
- unsigned int anDice[ 2 ];
+ unsigned int iTurn = 0;
+ unsigned int anDice[2];
- /* loop until all chequers are in home quadrant */
+ /* loop until all chequers are in home quadrant */
- while (nOut)
- {
- /* roll dice */
- if ( OSRQuasiRandomDice ( iTurn, iGame, nGames, anDice ) == FALSE)
- g_warning("Error in function OSRQuasiRandomDice");
+ while (nOut) {
+ /* roll dice */
+ if (OSRQuasiRandomDice(iTurn, iGame, nGames, anDice) == FALSE)
+ g_warning("Error in function OSRQuasiRandomDice");
- if ( anDice[ 0 ] < anDice[ 1 ] )
- swap_us ( anDice, anDice + 1 );
+ if (anDice[0] < anDice[1])
+ swap_us(anDice, anDice + 1);
- /* find and move best move */
- FindBestMoveOSR(anBoard, anDice, &nOut);
+ /* find and move best move */
+ FindBestMoveOSR(anBoard, anDice, &nOut);
- iTurn++;
- }
+ iTurn++;
+ }
- return iTurn;
+ return iTurn;
}
@@ -598,66 +599,66 @@ static unsigned int osr(unsigned int anBoard[25], const unsigned int iGame, cons
*/
static void
-rollOSR ( const unsigned int nGames, const unsigned int anBoard[ 25 ], const unsigned int nOut,
- float arProbs[], const unsigned int nMaxProbs,
- float arGammonProbs[], const unsigned int nMaxGammonProbs ) {
+rollOSR(const unsigned int nGames, const unsigned int anBoard[25], const unsigned int nOut,
+ float arProbs[], const unsigned int nMaxProbs, float arGammonProbs[], const unsigned int nMaxGammonProbs)
+{
+
+ unsigned int an[25];
+ unsigned short int anProb[32];
+ unsigned int i;
+ unsigned int n, m;
+ unsigned int iGame;
- unsigned int an[ 25 ];
- unsigned short int anProb[ 32 ];
- unsigned int i;
- unsigned int n, m;
- unsigned int iGame;
-
- int *anCounts = (int*) g_alloca(nMaxGammonProbs * sizeof(int));
+ int *anCounts = (int *) g_alloca(nMaxGammonProbs * sizeof(int));
- memset(anCounts, 0, sizeof(int) * nMaxGammonProbs);
+ memset(anCounts, 0, sizeof(int) * nMaxGammonProbs);
- for ( i = 0; i < nMaxProbs; ++i )
- arProbs[ i ] = 0.0f;
+ for (i = 0; i < nMaxProbs; ++i)
+ arProbs[i] = 0.0f;
- /* perform rollouts */
+ /* perform rollouts */
- for ( iGame = 0; iGame < nGames; ++iGame ) {
+ for (iGame = 0; iGame < nGames; ++iGame) {
- memcpy ( an, anBoard, sizeof ( an ) );
+ memcpy(an, anBoard, sizeof(an));
- /* do actual rollout */
+ /* do actual rollout */
- n = osr ( an, iGame, nGames, nOut );
+ n = osr(an, iGame, nGames, nOut);
- /* number of chequers in home quadrant */
+ /* number of chequers in home quadrant */
- m = 0;
- for ( i = 0; i < 6; ++i )
- m += an[ i ];
+ m = 0;
+ for (i = 0; i < 6; ++i)
+ m += an[i];
- /* update counts */
+ /* update counts */
- ++anCounts[ MIN( m == 15 ? n + 1 : n, nMaxGammonProbs - 1 ) ];
+ ++anCounts[MIN(m == 15 ? n + 1 : n, nMaxGammonProbs - 1)];
- /* get prob. from bearoff1 */
+ /* get prob. from bearoff1 */
- getBearoffProbs ( PositionBearoff ( an, pbc1->nPoints, pbc1->nChequers ), anProb );
+ getBearoffProbs(PositionBearoff(an, pbc1->nPoints, pbc1->nChequers), anProb);
- for ( i = 0; i < 32; ++i )
- arProbs[ MIN( n + i, nMaxProbs - 1 ) ] += anProb[ i ] / 65535.0f;
+ for (i = 0; i < 32; ++i)
+ arProbs[MIN(n + i, nMaxProbs - 1)] += anProb[i] / 65535.0f;
- }
+ }
- /* scale resulting probabilities */
+ /* scale resulting probabilities */
- for ( i = 0; i < (unsigned int)nMaxProbs; ++i ) {
- arProbs[ i ] /= nGames;
- /* printf ( "arProbs[%d]=%f\n", i, arProbs[ i ] ); */
- }
+ for (i = 0; i < (unsigned int) nMaxProbs; ++i) {
+ arProbs[i] /= nGames;
+ /* printf ( "arProbs[%d]=%f\n", i, arProbs[ i ] ); */
+ }
- /* calculate gammon probs.
- (prob. of getting inside home quadrant in i rolls */
+ /* calculate gammon probs.
+ * (prob. of getting inside home quadrant in i rolls */
- for ( i = 0; i < nMaxGammonProbs; ++i ) {
- arGammonProbs[ i ] = 1.0f * anCounts[ i ] / nGames;
- /* printf ( "arGammonProbs[%d]=%f\n", i, arGammonProbs[ i ] ); */
- }
+ for (i = 0; i < nMaxGammonProbs; ++i) {
+ arGammonProbs[i] = 1.0f * anCounts[i] / nGames;
+ /* printf ( "arGammonProbs[%d]=%f\n", i, arGammonProbs[ i ] ); */
+ }
}
@@ -678,121 +679,117 @@ rollOSR ( const unsigned int nGames, const unsigned int anBoard[ 25 ], const uns
*
*/
-static unsigned int osp ( const unsigned int anBoard[ 25 ], const unsigned int nGames,
- unsigned int an[ 25 ], float arProbs[ MAX_PROBS ],
- float arGammonProbs[ MAX_GAMMON_PROBS ] ) {
+static unsigned int
+osp(const unsigned int anBoard[25], const unsigned int nGames,
+ unsigned int an[25], float arProbs[MAX_PROBS], float arGammonProbs[MAX_GAMMON_PROBS])
+{
- int i, n;
- unsigned int nTotal, nOut;
- unsigned short int anProb[ 32 ];
+ int i, n;
+ unsigned int nTotal, nOut;
+ unsigned short int anProb[32];
- /* copy board into an, and find total number of chequers left,
- and number of chequers outside home */
+ /* copy board into an, and find total number of chequers left,
+ * and number of chequers outside home */
- nTotal = nOut = 0;
+ nTotal = nOut = 0;
- memcpy( an, anBoard, 25 * sizeof( int ) );
+ memcpy(an, anBoard, 25 * sizeof(int));
- for ( i = 0; i < 25; ++i ) {
- /* total number of chequers left */
- nTotal += anBoard[ i ];
- if ( i > 5 )
- nOut += anBoard[ i ];
- }
+ for (i = 0; i < 25; ++i) {
+ /* total number of chequers left */
+ nTotal += anBoard[i];
+ if (i > 5)
+ nOut += anBoard[i];
+ }
- if ( nOut > 0 )
- /* chequers outside home: do one sided rollout */
- rollOSR ( nGames, an, nOut,
- arProbs, MAX_PROBS,
- arGammonProbs, MAX_GAMMON_PROBS );
- else {
- /* chequers inde home: use BEAROFF2 */
+ if (nOut > 0)
+ /* chequers outside home: do one sided rollout */
+ rollOSR(nGames, an, nOut, arProbs, MAX_PROBS, arGammonProbs, MAX_GAMMON_PROBS);
+ else {
+ /* chequers inde home: use BEAROFF2 */
- /* no gammon possible */
- for ( i = 0; i < MAX_GAMMON_PROBS; ++i )
- arGammonProbs[ i ] = 0.0f;
+ /* no gammon possible */
+ for (i = 0; i < MAX_GAMMON_PROBS; ++i)
+ arGammonProbs[i] = 0.0f;
- if ( nTotal == 15 )
- arGammonProbs[ 1 ] = 1.0f;
- else
- arGammonProbs[ 0 ] = 1.0f;
+ if (nTotal == 15)
+ arGammonProbs[1] = 1.0f;
+ else
+ arGammonProbs[0] = 1.0f;
- /* get probs from BEAROFF2 */
+ /* get probs from BEAROFF2 */
- for ( i = 0; i < MAX_PROBS; ++i )
- arProbs[ i ] = 0.0f;
+ for (i = 0; i < MAX_PROBS; ++i)
+ arProbs[i] = 0.0f;
- getBearoffProbs ( PositionBearoff ( anBoard, pbc1->nPoints, pbc1->nChequers), anProb );
+ getBearoffProbs(PositionBearoff(anBoard, pbc1->nPoints, pbc1->nChequers), anProb);
- for ( i = 0; i < 32; ++i ) {
- n = MIN( i, MAX_PROBS - 1 );
- arProbs[ n ] += anProb[ i ] / 65535.0f;
- /* printf ( "arProbs[%d]=%f\n", n, arProbs[n] ); */
- }
+ for (i = 0; i < 32; ++i) {
+ n = MIN(i, MAX_PROBS - 1);
+ arProbs[n] += anProb[i] / 65535.0f;
+ /* printf ( "arProbs[%d]=%f\n", n, arProbs[n] ); */
+ }
- }
+ }
- return nTotal;
+ return nTotal;
}
static float
-bgProb ( const unsigned int anBoard[ 25 ],
- const int fOnRoll,
- const unsigned int nTotal,
- const float arProbs[],
- const unsigned int nMaxProbs ) {
+bgProb(const unsigned int anBoard[25],
+ const int fOnRoll, const unsigned int nTotal, const float arProbs[], const unsigned int nMaxProbs)
+{
- unsigned int nTotPipsHome = 0;
- unsigned int i, j;
- float r, s;
- unsigned short int anProb[ 32 ];
+ unsigned int nTotPipsHome = 0;
+ unsigned int i, j;
+ float r, s;
+ unsigned short int anProb[32];
- /* total pips before out of opponent's home quadrant */
+ /* total pips before out of opponent's home quadrant */
- for ( i = 18; i < 25; ++i )
- nTotPipsHome += anBoard[ i ] * ( i - 17 );
+ for (i = 18; i < 25; ++i)
+ nTotPipsHome += anBoard[i] * (i - 17);
- r = 0.0f;
+ r = 0.0f;
- if ( nTotPipsHome ) {
+ if (nTotPipsHome) {
- /* ( nTotal + 3 ) / 4 - 1: number of rolls before opponent is off. */
- /* (nTotPipsHome + 2) / 3: numbers of rolls before I'm out of
- opponent's home quadrant (with consequtive 2-1's) */
+ /* ( nTotal + 3 ) / 4 - 1: number of rolls before opponent is off. */
+ /* (nTotPipsHome + 2) / 3: numbers of rolls before I'm out of
+ * opponent's home quadrant (with consequtive 2-1's) */
- if ( ( nTotal + 3 ) / 4 - 1 <= ( nTotPipsHome + 2 ) / 3 )
- {
- /* backgammon is possible */
+ if ((nTotal + 3) / 4 - 1 <= (nTotPipsHome + 2) / 3) {
+ /* backgammon is possible */
- /* get "bear-off" prob (for getting out of opp.'s home quadr.) */
-
- /* FIXME: this ignores chequers on the bar */
+ /* get "bear-off" prob (for getting out of opp.'s home quadr.) */
- getBearoffProbs ( PositionBearoff ( anBoard + 18, pbc1->nPoints, pbc1->nChequers ), anProb );
+ /* FIXME: this ignores chequers on the bar */
- for ( i = 0; i < nMaxProbs; ++i ) {
+ getBearoffProbs(PositionBearoff(anBoard + 18, pbc1->nPoints, pbc1->nChequers), anProb);
- if ( arProbs[ i ] > 0.0f ) {
+ for (i = 0; i < nMaxProbs; ++i) {
- s = 0.0f;
+ if (arProbs[i] > 0.0f) {
- for (j = i + !fOnRoll; j < 32; ++j)
- s += anProb[ j ] / 65535.0f;
+ s = 0.0f;
- r += s * arProbs[ i ];
+ for (j = i + !fOnRoll; j < 32; ++j)
+ s += anProb[j] / 65535.0f;
- }
+ r += s * arProbs[i];
- }
+ }
- }
+ }
+
+ }
- }
+ }
- return r;
+ return r;
}
@@ -811,105 +808,103 @@ bgProb ( const unsigned int anBoard[ 25 ],
*/
extern void
-raceProbs ( const TanBoard anBoard, const unsigned int nGames,
- float arOutput[ NUM_OUTPUTS ],
- float arMu[ 2 ] ) {
-
- TanBoard an;
- float aarProbs[ 2 ][ MAX_PROBS ];
- float aarGammonProbs[ 2 ][ MAX_PROBS ];
- float arG[ 2 ], arBG[ 2 ];
+raceProbs(const TanBoard anBoard, const unsigned int nGames, float arOutput[NUM_OUTPUTS], float arMu[2])
+{
- unsigned int anTotal[ 2 ];
+ TanBoard an;
+ float aarProbs[2][MAX_PROBS];
+ float aarGammonProbs[2][MAX_PROBS];
+ float arG[2], arBG[2];
- int i, j, k;
+ unsigned int anTotal[2];
- float w, s;
+ int i, j, k;
- /* Seed set to ensure that OSR are reproducable */
+ float w, s;
- init_genrand ( 0, &mti, mt );
+ /* Seed set to ensure that OSR are reproducable */
- for ( i = 0; i < 5; ++i )
- arOutput[ i ] = 0.0f;
+ init_genrand(0, &mti, mt);
- for ( i = 0; i < 2; ++i )
- anTotal[ i ] = osp(anBoard[ i ], nGames, an[ i ], aarProbs[ i ], aarGammonProbs[ i ]);
+ for (i = 0; i < 5; ++i)
+ arOutput[i] = 0.0f;
- /* calculate OUTPUT_WIN */
+ for (i = 0; i < 2; ++i)
+ anTotal[i] = osp(anBoard[i], nGames, an[i], aarProbs[i], aarGammonProbs[i]);
- w = 0;
-
- for ( i = 0; i < MAX_PROBS; ++i ) {
-
- /* calculate the prob. of the opponent using more than i rolls
- to bear off */
-
- s = 0.0f;
- for ( j = i; j < MAX_PROBS; ++j )
- s += aarProbs[ 0 ][ j ];
-
- /* winning chance is: prob. of me bearing off in i rolls times
- prob. the opponent doesn't bear off in i rolls */
-
- w += aarProbs[ 1 ][ i ] * s;
+ /* calculate OUTPUT_WIN */
- }
+ w = 0;
- arOutput[ OUTPUT_WIN ] = MIN( w, 1.0f );
+ for (i = 0; i < MAX_PROBS; ++i) {
- /* calculate gammon and backgammon probs */
+ /* calculate the prob. of the opponent using more than i rolls
+ * to bear off */
- for ( i = 0; i < 2; ++i ) {
+ s = 0.0f;
+ for (j = i; j < MAX_PROBS; ++j)
+ s += aarProbs[0][j];
- arG[ i ] = 0.0f;
- arBG[ i ] = 0.0f;
+ /* winning chance is: prob. of me bearing off in i rolls times
+ * prob. the opponent doesn't bear off in i rolls */
- if ( anTotal[ ! i ] == 15 ) {
+ w += aarProbs[1][i] * s;
- /* gammon and backgammon possible */
+ }
- for ( j = 0; j < MAX_GAMMON_PROBS; ++j ) {
+ arOutput[OUTPUT_WIN] = MIN(w, 1.0f);
- /* chance of opponent having borne all chequers of
- within j rolls */
+ /* calculate gammon and backgammon probs */
- s = 0.0f;
- for ( k = 0; k < j + i; ++k )
- s += aarProbs[ i ][ k ];
+ for (i = 0; i < 2; ++i) {
- /* gammon chance */
+ arG[i] = 0.0f;
+ arBG[i] = 0.0f;
- arG[ i ] += aarGammonProbs[ ! i ][ j ] * s;
+ if (anTotal[!i] == 15) {
- }
+ /* gammon and backgammon possible */
- if ( arG[ i ] > 0.0f )
- /* calculate backgammon probs */
- arBG[ i ] = bgProb ( an[ ! i ], i, anTotal[ i ],
- aarProbs[ i ], MAX_PROBS );
+ for (j = 0; j < MAX_GAMMON_PROBS; ++j) {
- }
+ /* chance of opponent having borne all chequers of
+ * within j rolls */
- }
+ s = 0.0f;
+ for (k = 0; k < j + i; ++k)
+ s += aarProbs[i][k];
- arOutput[ OUTPUT_WINGAMMON ] = MIN( arG[ 1 ], 1.0f );
- arOutput[ OUTPUT_LOSEGAMMON ] = MIN( arG[ 0 ], 1.0f );
- arOutput[ OUTPUT_WINBACKGAMMON ] = MIN( arBG[ 1 ], 1.0f );
- arOutput[ OUTPUT_LOSEBACKGAMMON ] = MIN( arBG[ 0 ], 1.0f );
+ /* gammon chance */
- /* calculate average number of rolls to bear off */
+ arG[i] += aarGammonProbs[!i][j] * s;
- if ( arMu ) {
+ }
+ if (arG[i] > 0.0f)
+ /* calculate backgammon probs */
+ arBG[i] = bgProb(an[!i], i, anTotal[i], aarProbs[i], MAX_PROBS);
- for ( i = 0; i < 2; ++i ) {
- arMu[ i ] = 0.0f;
- for ( j = 0; j < MAX_PROBS; ++j )
- arMu[ i ] += 1.0f * j * aarProbs[ i ][ j ];
+ }
}
- }
+ arOutput[OUTPUT_WINGAMMON] = MIN(arG[1], 1.0f);
+ arOutput[OUTPUT_LOSEGAMMON] = MIN(arG[0], 1.0f);
+ arOutput[OUTPUT_WINBACKGAMMON] = MIN(arBG[1], 1.0f);
+ arOutput[OUTPUT_LOSEBACKGAMMON] = MIN(arBG[0], 1.0f);
+
+ /* calculate average number of rolls to bear off */
+
+ if (arMu) {
+
+
+ for (i = 0; i < 2; ++i) {
+ arMu[i] = 0.0f;
+ for (j = 0; j < MAX_PROBS; ++j)
+ arMu[i] += 1.0f * j * aarProbs[i][j];
+
+ }
+
+ }
}