/* db.c Copyright (C) 1994,1995,1996,1997 Lambert Klasen & Detlef Steuer klasen@asterix.uni-muenster.de steuer@gigamain.statistik.uni-dortmund.de This file is free source code; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See COPYING for more details. */ #include #include double E_Werte[54264]; double Distribution[54264][30]; unsigned short database[54264][30]; long int NaufM[16][7]; long int Binomial[7][7]; long int Nummeroffset[7][8][16]; int pin[7] = {15, 0, 0, 0, 0, 0, 0}; long int fak(int n) { if (n < 2) return (1); else return (n * fak(n - 1)); } long int binomial(int n, int m) { return (fak(n) / fak(m) / fak(n-m)); } long int naufm(int n, int m) { if (n < m) return (0); if (m == 1) return (1); return (naufm(n - 1, m) + naufm(n - 1, m - 1)); } void set_naufm() { int i, j; for (i=1; i<16; i++) { for (j=1; j<7; j++) { NaufM[i][j] = naufm(i, j); } } } void set_binom() { int i, j; for (i = 1; i < 7; i++) { for (j = 1; j < 7; j++) { Binomial[i][j] = binomial(i, j); } } } void set_offset() { int start, next, summe, steine; int start2, steine2, summanden2; for (start = 0; start < 6; start++) { for (next = 1; start + next < 7; next++) { for (summe = 1; summe < 16; summe++) { Nummeroffset[start][next][summe] = 0; for (start2 = start; start2 < start + next; start2++) { for (steine = 1; steine < summe; steine++) { for (summanden2 = 1; summanden2 < 6 - start2 + 1; summanden2++) { Nummeroffset[start][next][summe] += Binomial[6 - start2][summanden2] * NaufM[steine][summanden2]; } } } } } } } long int rel_Stellungsnummer(int startpin) { int summe = 0, summanden, steine, start; int i, nextpin; long int nummer = 0L; for (i = startpin + 1; i < 7; i++) { summe += pin[i]; } if (summe == 0) return (0); i = startpin + 1; while (pin[i] == 0 && i < 7) { i++; } nextpin = i - startpin; nummer += nextpin; nummer += Nummeroffset[startpin][nextpin][summe]; nummer += rel_Stellungsnummer(startpin + nextpin); return (nummer); } long calc(int anz, int w1, int w2, int w3, int w4) { int wurf[5] = {0, w1, w2, w3, w4}, rest[5]; double minewert = 100.0, tmpwert; int wurfend, maxpin = 0, i, feld, j, k; int start, end, wf; long tmpnummer, minnummer = 0L; if (pin[1] + pin[2] + pin[3] + pin[4] + pin[5] + pin[6] == 0) return (minnummer); if (anz == 0) return ((long) rel_Stellungsnummer(0)); for (i = 1; i < 7; i++) { if (pin[i] > 0) maxpin = i; } wurfend = anz; if (anz > 2) wurfend = 1; if (anz == 2) { if (wurf[1] == wurf[2]) wurfend = 1; else wurfend = 2; } for (j = 1; j < wurfend + 1; j++) { if (wurf[j] < maxpin) { start = wurf[j]; end = maxpin; } else { start = end = maxpin; } for (feld = end; feld > start - 1; feld--) { if (pin[feld] > 0) { pin[feld]--; if (feld > wurf[j]) pin[feld - wurf[j]]++; for (k = 1; k < 5; k++) { if (k < j) rest[k] = wurf[k]; if (k > j) rest[k - 1] = wurf[k]; } rest[4] = 0; tmpnummer = calc(anz - 1, rest[1], rest[2], rest[3], rest[4]); tmpwert = E_Werte[tmpnummer]; if (tmpwert < minewert) { minewert = tmpwert; minnummer = tmpnummer; } pin[feld]++; if (feld > wurf[j]) pin[feld - wurf[j]]--; } } } return (minnummer); } void set_V_Werte() { long int zugnummer = 0L, minstell; double erwartung; double aktv[30]; double altv[30]; FILE *fid; int z1, z2, i,j, tmp, maxpin = 0; fid = fopen("xgammon.db", "w+b"); do { if (maxpin < 6) { pin[maxpin++]--; pin[maxpin]++; } else { i = 6; while (pin[i - 1] == 0) i--; tmp = pin[6]; pin[6] = 0; pin[i] = 1 + tmp; pin[i - 1]--; maxpin = i; } zugnummer++; printf(" %d\r",zugnummer); erwartung = 0.0; for (i = 0; i < 30; i++) { aktv[i] = 0.0; } for (z1 = 1; z1 < 7; z1++) { for (z2 = z1; z2 < 7; z2++) { if (z1 == z2) { minstell = calc(4, z1, z1, z1, z1); if (minstell == 0) aktv[0] += 1.0; else { for (i = 0; i < 29; i++) aktv[i + 1] += Distribution[minstell][i]; } } else { minstell = calc(2, z1, z2, 0, 0); if (minstell == 0) aktv[0] += 2.0; else { for (i = 0; i < 29; i++) { aktv[i + 1] += 2.0 * Distribution[minstell][i]; } } } } } for (i = 0; i < 29; i++) { Distribution[zugnummer][i] = aktv[i]/36.0; erwartung += Distribution[zugnummer][i] * (double) (i + 1); /*printf("%f\n", erwartung);*/ } E_Werte[zugnummer] = erwartung ; /*printf(" %.13f\n",erwartung);*/ } while (pin[6] != 15); for (i=0; i< 54263; i++) { for (j=0; j<18; j++) *(&database[1][0] + i*18 +j) = (unsigned short) (*(&Distribution[1][0]+i*30 + j) * 65535.0) ; } fwrite(&database[1][0], sizeof(unsigned short), 18 * 54263, fid); fclose(fid); } main() { set_binom(); set_naufm(); set_offset(); set_V_Werte(); return 0; }