/************************************************************************** * * THOR 3.4 Reflexion Engine * * Copyright (C) 1990-1994 Sylvain QUIN * * Othello II v2.53 - 08/02/2004 * * Copyright (C) 2000-2004 François LEIBER * * This file is part of Othello II. * * Othello II is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Othello II 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 the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * *************************************************************************/ short fgp_j(short *, short); short fgp_o(short *, short); short fscor_j(short *, short); short fscor_o(short *, short); short Ordre[60] = { 10, 17, 73, 80, 30, 33, 57, 60, 31, 32, 39, 42, 48, 51, 58, 59, 22, 23, 38, 43, 47, 52, 67, 68, 12, 15, 28, 35, 55, 62, 75, 78, 21, 24, 29, 34, 56, 61, 66, 69, 13, 14, 37, 44, 46, 53, 76, 77, 11, 19, 16, 26, 64, 71, 74, 79, 20, 25, 65, 70 }; short CoeffPos = 13; // Coefficients permettant de moduler la réflexion short CoeffNbre = 10; short CoeffMob = 10; short CompteurTotal = 0; // Temps de réflexion total short CompteurPrecedent = 0; // Dernier temps où l'on a avancé la barre short Freq = 0; // Fréquence d'affichage de la réflexion short TempsMax = 0; // Temps maximal pour étudier Freq coups short TempsMin = 0; // Temps minimal pour étudier Freq coups short ProfMax = 0; // Profondeur maximale atteinte short NbreCoups2 = 0; // Pour les noeuds de alfbet_x short Memcp[20][19] = { }; // Zones des mémorisations short Casvid[1200] = { }; // Zone de stockage des cases vides short *T_v[30] = { }; // Pointeurs vers les cases vides short T2v[8][32] = { }; // Zone de stockages vides numéro 2 short Coup1[32] = { }; // Coups possibles niveau 1 short Coup2[500] = { }; // Coups niveau 2 short Coup3[500] = { }; // Coups niveau 3 short ListV[60] = { }; // Liste des cases vides short Repo1[32] = { }; // Vers les réponses au niveau 1 short Ponder[20] = { }; // Zones des pondérations short Alfbet[20] = { }; // Zones d'alpha-beta short Pass[20] = { }; // Flags de passe short Prmax = 0; // Profondeur maxi d'analyse short Prfact = 0; // Profondeur active d'analyse short Resul = 0; // Résultat utilisé en recherche finale short Nb_cv = 0; // Nombre de cases vides short Phase = 0; // Phase de la partie short P_cp2 = 0; // Pointe sur Coup2[] libre short C2_ac = 0; // Coup2 actif ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// short rest_hor(short np, short coul) { short *sto = Memcp[Prfact]; short diff; long couptemp; while (np--) Tableau[*sto++] = coul; Nb_cv++; NbreCoups++; if ((NbreCoups - 1) % Freq - Freq + 1 + NbreCoups2 >= 0) // Tous les Freq coups, affiche le stade de la réflexion { avance_barre(61 - 58 * ((long)Compteur) / CompteurTotal, Joueur); #ifdef _89 if ((_rowread(0xfffd) & 64) != 0) off(); #else if ((_rowread(0xff7f) & 32) != 0) off(); #endif if (Compteur == 0) { NbreCoups--; return 0; } else { couptemp = NbreCoups + NbreCoups2; NbreCoups2 = 0; NbreCoups += Freq - (NbreCoups % Freq); print_nbre_examin(Joueur); NbreCoups = couptemp; diff = CompteurPrecedent - Compteur; if (TempsMin > diff) TempsMin = diff; if (TempsMax < diff) TempsMax = diff; CompteurPrecedent = Compteur; return 1; } } return 1; } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// short restor(short cp, short np, short coul) { if (coul == Adversaire) Resul -= np + np + 1; else Resul += np + np + 1; Tableau[cp] = VIDE; return rest_hor(np, coul); } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// short entour(short coup) { short *ini = Tableau + coup; if (*(ini - 1) == VIDE) return 0; if (*(ini + 1) == VIDE) return 0; if (*(ini - 9) == VIDE) return 0; if (*(ini + 9) == VIDE) return 0; if (*(ini - 8) == VIDE) return 0; if (*(ini + 8) == VIDE) return 0; if (*(ini - 10) == VIDE) return 0; if (*(ini + 10) == VIDE) return 0; return 1; } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// short nbcasb(short prem, short inc) { short x, r = 0; for (x = 0; x < 6; prem += inc, x++) if (Tableau[prem] != VIDE) r++; return r; } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// short t_pris(short coup, short coul) { short *ptt, *ini = Tableau + coup; short adv = coul ^ 1; if (*(ptt = ini - 1) == adv) { while (*(--ptt) == adv) ; if (*ptt == coul) return 1; } if (*(ptt = ini + 1) == adv) { while (*(++ptt) == adv) ; if (*ptt == coul) return 1; } if (*(ptt = ini - 9) == adv) { while (*(ptt -= 9) == adv) ; if (*ptt == coul) return 1; } if (*(ptt = ini + 9) == adv) { while (*(ptt += 9) == adv) ; if (*ptt == coul) return 1; } if (*(ptt = ini - 10) == adv) { while (*(ptt -= 10) == adv) ; if (*ptt == coul) return 1; } if (*(ptt = ini + 10) == adv) { while (*(ptt += 10) == adv) ; if (*ptt == coul) return 1; } if (*(ptt = ini - 8) == adv) { while (*(ptt -= 8) == adv) ; if (*ptt == coul) return 1; } if (*(ptt = ini + 8) == adv) { while (*(ptt += 8) == adv) ; if (*ptt == coul) return 1; } return 0; } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// short nbprise(short coup, short coul) { short *ptt, *ini = Tableau + coup; short y, nb = 0, adv = coul ^ 1; if (*(ptt = ini - 1) == adv) { y = 1; while (*(--ptt) == adv) y++; if (*ptt == coul) nb += y; } if (*(ptt = ini + 1) == adv) { y = 1; while (*(++ptt) == adv) y++; if (*ptt == coul) nb += y; } if (*(ptt = ini - 9) == adv) { y = 1; while (*(ptt -= 9) == adv) y++; if (*ptt == coul) nb += y; } if (*(ptt = ini + 9) == adv) { y = 1; while (*(ptt += 9) == adv) y++; if (*ptt == coul) nb += y; } if (*(ptt = ini - 10) == adv) { y = 1; while (*(ptt -= 10) == adv) y++; if (*ptt == coul) nb += y; } if (*(ptt = ini + 10) == adv) { y = 1; while (*(ptt += 10) == adv) y++; if (*ptt == coul) nb += y; } if (*(ptt = ini - 8) == adv) { y = 1; while (*(ptt -= 8) == adv) y++; if (*ptt == coul) nb += y; } if (*(ptt = ini + 8) == adv) { y = 1; while (*(ptt += 8) == adv) y++; if (*ptt == coul) nb += y; } return nb; } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// short joucoup(short coup, short coul) { short *ptt, *sto = Memcp[Prfact], *ini = Tableau + coup; short y, cp2, np = 0, adv = coul ^ 1; if (*(ptt = ini + 1) == adv) { y = 1; while (*(++ptt) == adv) y++; if (*ptt == coul) { np += y; cp2 = coup; while (y--) Tableau[*sto++ = (++cp2)] = coul; } } if (*(ptt = ini - 1) == adv) { y = 1; while (*(--ptt) == adv) y++; if (*ptt == coul) { np += y; cp2 = coup; while (y--) Tableau[*sto++ = (--cp2)] = coul; } } if (*(ptt = ini + 9) == adv) { y = 1; while (*(ptt += 9) == adv) y++; if (*ptt == coul) { np += y; cp2 = coup; while (y--) Tableau[*sto++ = (cp2 += 9)] = coul; } } if (*(ptt = ini - 9) == adv) { y = 1; while (*(ptt -= 9) == adv) y++; if (*ptt == coul) { np += y; cp2 = coup; while (y--) Tableau[*sto++ = (cp2 -= 9)] = coul; } } if (*(ptt = ini + 10) == adv) { y = 1; while (*(ptt += 10) == adv) y++; if (*ptt == coul) { np += y; cp2 = coup; while (y--) Tableau[*sto++ = (cp2 += 10)] = coul; } } if (*(ptt = ini - 10) == adv) { y = 1; while (*(ptt -= 10) == adv) y++; if (*ptt == coul) { np += y; cp2 = coup; while (y--) Tableau[*sto++ = (cp2 -= 10)] = coul; } } if (*(ptt = ini + 8) == adv) { y = 1; while (*(ptt += 8) == adv) y++; if (*ptt == coul) { np += y; cp2 = coup; while (y--) Tableau[*sto++ = (cp2 += 8)] = coul; } } if (*(ptt = ini - 8) == adv) { y = 1; while (*(ptt -= 8) == adv) y++; if (*ptt == coul) { np += y; cp2 = coup; while (y--) Tableau[*sto++ = (cp2 -= 8)] = coul; } } return np; } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// short prise(short coup, short coul) { short np; if ((np = joucoup(coup, coul)) == 0) return 0; Tableau[coup] = coul; Nb_cv--; if (coul == Adversaire) Resul -= np + np + 1; else Resul += np + np + 1; return np; } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// short valbor(short *lign, short coul) { short *ptt = lign; short c, adv = coul ^ 1, x, pc = 0, pa = 0, pv; for (x = 0; x < 8; x++) { if ((c = *ptt++) == coul) pc++; else if (c == adv) pa++; } if ((pc + pa) == 8) return 4 * (pc - pa); if ((pc + pa) == 0) return 0; pa = pc = 0; c = *(ptt = lign); if (c != VIDE) { pv = 2; while (*(++ptt) == c) pv++; if (c == coul) pc += pv; else pa += pv; } c = *(ptt = lign + 7); if (c != VIDE) { pv = 2; while (*(--ptt) == c) pv++; if (c == coul) pc += pv; else pa += pv; } return 4 * (pc - pa); } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// short valueC(short coup, short coul) { short x2; if (coup > 27 && coup < 63) return 14; x2 = coup % 9; if (x2 > 2 && x2 < 7) return 14; x2 = Phase + Phase / 2; switch (coup) { case 11: if (Tableau[10] != VIDE) return 15; if (nbcasb(11, 1) < 3) return 11 - x2; if (Tableau[16] == coul) return 17 + x2; return 12 - x2; case 16: if (Tableau[17] != VIDE) return 15; if (nbcasb(11, 1) < 3) return 11 - x2; if (Tableau[11] == coul) return 17 + x2; return 12 - x2; case 19: if (Tableau[10] != VIDE) return 15; if (nbcasb(19, 9) < 3) return 11 - x2; if (Tableau[64] == coul) return 17 + x2; return 12 - x2; case 64: if (Tableau[73] != VIDE) return 15; if (nbcasb(19, 9) < 3) return 11 - x2; if (Tableau[19] == coul) return 17 + x2; return 12 - x2; case 26: if (Tableau[17] != VIDE) return 15; if (nbcasb(26, 9) < 3) return 11 - x2; if (Tableau[71] == coul) return 17 + x2; return 12 - x2; case 71: if (Tableau[80] != VIDE) return 15; if (nbcasb(26, 9) < 3) return 11 - x2; if (Tableau[26] == coul) return 17 + x2; return 12 - x2; case 74: if (Tableau[73] != VIDE) return 15; if (nbcasb(74, 1) < 3) return 11 - x2; if (Tableau[79] == coul) return 17 + x2; return 12 - x2; case 79: if (Tableau[80] != VIDE) return 15; if (nbcasb(74, 1) < 3) return 11 - x2; if (Tableau[74] == coul) return 17 + x2; return 12 - x2; case 20: if (Tableau[10] != VIDE) return 15; return 8 - x2; case 25: if (Tableau[17] != VIDE) return 15; return 8 - x2; case 65: if (Tableau[73] != VIDE) return 15; return 8 - x2; case 70: if (Tableau[80] != VIDE) return 15; return 8 - x2; case 10: case 17: case 73: case 80: if (Prmax - Prfact < 2) return 21; return 17; } return 14; } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// short liberte(short coul) { short m = 0, adv = coul ^ 1, c, x = 0, lim; if (Phase < 4) lim = 60; else lim = 56; for (x = 0; x < lim; x++) { if (Tableau[c = Ordre[x]] == VIDE) if (t_pris(c, coul) != 0) { m += 2; if (t_pris(c, adv) == 0) m += 5; } } if (m < 49) return m; return (m + 48) / 2; } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// short evalue(short c, short coul) { short bord[8]; short x, pond, res = 0; pond = valueC(c, coul ^ 1); switch (Prmax - Prfact) { case 1: res = (Prfact % 2 == 0) ? Resul : -Resul; if (Phase < 2) res += res; else { if (Nb_cv < 48) res = (res * 16) / (64 - Nb_cv); res = -2 * res; } return (CoeffPos * pond + CoeffNbre * res); case 2: for (x = 0; x < 8; x++) bord[x] = Tableau[x + 10]; pond -= valbor(bord, coul); for (x = 0; x < 8; x++) bord[x] = Tableau[x + 73]; pond -= valbor(bord, coul); for (x = 0; x < 8; x++) bord[x] = Tableau[9 * x + 10]; pond -= valbor(bord, coul); for (x = 0; x < 8; x++) bord[x] = Tableau[9 * x + 17]; pond -= valbor(bord, coul); if (Phase > 1) { if (Tableau[40] == coul) pond--; if (Tableau[41] == coul) pond--; if (Tableau[49] == coul) pond--; if (Tableau[50] == coul) pond--; } case 3: res = liberte(coul); break; } return (CoeffPos * pond - CoeffNbre * res); } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void cre_rep(short n) { char cp[32]; short coup, x = 0, y = 0; Repo1[n] = P_cp2; while ((coup = ListV[x++]) != 0) if (Tableau[coup] == VIDE) if (t_pris(coup, Adversaire) != 0) { if (entour(coup) != 0) Coup2[P_cp2++] = coup; else cp[y++] = coup; } if (y != 0) for (x = 0; x < y; x++) Coup2[P_cp2++] = cp[x]; Coup2[P_cp2++] = 0; } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void cre_vid(short *vid, short c3) { short *pt = ListV; short c; if ((c3 = Coup3[c3]) != 0) *vid++ = c3; while ((c = *pt++) != 0) if (Tableau[c] == VIDE) if (c != c3) *vid++ = c; *vid = 0; } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void addkill(short coup) { short x; if (ListV[0] == coup) return; for (x = 1; x < 60; x++) if (coup == ListV[x]) { ListV[x] = ListV[x - 1]; ListV[x - 1] = coup; return; } } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// short alfbet_x(short coul) { short c, v, alf, pass = -1; short *pr = ListV; alf = Alfbet[Prfact - 2] + Ponder[Prfact - 1] - Ponder[Prfact - 2]; while ((c = *pr++) != 0) { if (Tableau[c] != VIDE) continue; if ((v = nbprise(c, coul)) == 0) continue; NbreCoups2++; if (coul == Adversaire) v = v + v + 1 - Resul; else v = v + v + 1 + Resul; pass = 0; if (Phase < 2) v += v; else { if (Nb_cv < 48) v = (v * 16) / (64 - Nb_cv); v = -2 * v; } if ((v = CoeffPos * valueC(c, coul) + CoeffNbre * v) > alf) if ((Ponder[Prfact - 1] - (alf = v)) <= Alfbet[Prfact - 1]) break; } if (pass == 0) return alf; return 0; } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// short alfbet_n(short coul, short *lstcp, short prev) { short c, n, v, nu, pass; short *pr = T_v[Prfact]; while ((*pr++ = *lstcp++) != 0) ; pr = T_v[Prfact]; Alfbet[Prfact] = Alfbet[Prfact - 2] + Ponder[Prfact - 1] - Ponder[Prfact - 2]; nu = pass = -1; while ((c = *pr++) != 0) { if (Tableau[c] != VIDE) continue; if ((n = prise(c, coul)) == 0) continue; nu++; pass = v = 0; Ponder[Prfact] = evalue(c, coul ^ 1); if (++Prfact < Prmax) { if (Prfact + 1 < Prmax) v = alfbet_n(coul ^ 1, ListV, c); else v = alfbet_x(coul ^ 1); } Prfact--; if (restor(c, n, coul ^ 1) == 0) return 0; if ((v = Ponder[Prfact] - v) > Alfbet[Prfact]) { if (Prfact == 2) Coup3[C2_ac] = c; if ((Ponder[Prfact - 1] - (Alfbet[Prfact] = v)) <= Alfbet[Prfact - 1]) { if (nu != 0) addkill(c); break; } } } if (pass == 0) return Alfbet[Prfact]; if (prev == 0) { if (Resul == 0) return 0; if (Resul > 0) return (coul == Joueur) ? 100 : -100; return (coul == Joueur) ? -100 : 100; } v = 0; if (++Prfact < Prmax) { if (Prfact + 1 < Prmax) v = alfbet_n(coul ^ 1, ListV, c); else v = alfbet_x(coul ^ 1); } Prfact--; return (-v); } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// short alfbet_1(short prem) { short *vid = T_v[1]; short c, n, v, x, pass, base = Repo1[prem]; pass = x = -1; Alfbet[1] = -9999; while ((c = Coup2[C2_ac = base + (++x)]) != 0) { n = prise(c, Adversaire); v = pass = 0; Ponder[1] = evalue(c, Joueur); cre_vid(vid, base + x); if (++Prfact < Prmax) v = alfbet_n(Joueur, vid, c); Prfact--; if (restor(c, n, Joueur) == 0) return 0; if ((v = Ponder[1] - v) > Alfbet[1]) { n = Coup3[C2_ac]; while (base < C2_ac--) { Coup2[C2_ac + 1] = Coup2[C2_ac]; Coup3[C2_ac + 1] = Coup3[C2_ac]; } Coup2[base] = c; Coup3[base] = n; if ((Ponder[0] - (Alfbet[1] = v)) <= Alfbet[0]) break; } } if (pass == 0) return Alfbet[1]; cre_vid(vid, base); Ponder[1] = v = 0; if (++Prfact < Prmax) v = alfbet_n(Joueur, vid, c); Prfact--; return (-v); } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void alfbet_0(void) { short c, n, v, x = -1, r = Alfbet[0]; Alfbet[Prfact = 0] = -9999; while ((c = Coup1[++x]) != 0) { n = prise(c, Joueur); Ponder[0] = evalue(c, Adversaire); if (Prmax == 2) cre_rep(x); Prfact++; v = alfbet_1(x); Prfact--; if (restor(c, n, Adversaire) == 0) { if (Alfbet[0] == -9999) Alfbet[0] = r; Prmax = 99; break; } if ((v = Ponder[0] - v) > Alfbet[0]) { Alfbet[0] = v; r = Repo1[v = x]; while (v--) { Coup1[v + 1] = Coup1[v]; Repo1[v + 1] = Repo1[v]; } Coup1[0] = c; Repo1[0] = r; } } return; } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// short * majlst2(short *ini, short *tab, short coul) { short *sto, cp[32], val[32]; short x, y, z, nc = 0, nb = 0, c1, adv = coul ^ 1; if (Prfact == 3) ini = ListV; while ((c1 = *ini++) != 0) if (Tableau[c1] == VIDE) cp[nb++] = *tab++ = c1; *tab = 0; for (x = 0; x < Nb_cv; x++) { if ((nb = joucoup(c1 = cp[x], coul)) > 0) { Tableau[c1] = coul; for (y = z = 0; y < Nb_cv; y++) if (x != y) if (t_pris(cp[y], adv) != 0) z++; cp[nc] = c1; val[nc] = nc + z; nc++; sto = Memcp[Prfact]; Tableau[c1] = VIDE; while (nb--) Tableau[*sto++] = adv; } } cp[nc] = 0; y = 0; while (y == 0 && nc > 1) { for (x = y = 1; x < nc; x++) if (val[x - 1] > val[x]) { y = val[x - 1]; val[x - 1] = val[x]; val[x] = y; y = cp[x - 1]; cp[x - 1] = cp[x]; cp[x] = y; y = 0; } nc--; } tab = T2v[Prfact]; x = 0; ini = cp; while ((c1 = *ini++) != 0) { if (entour(c1) != 0) *tab++ = c1; else cp[x++] = c1; } if (x != 0) for (y = 0; y < x; y++) *tab++ = cp[y]; *tab = 0; return T2v[Prfact]; } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// short * majlst(short *ini, short *tab) { short *ret = tab, cp[32]; short x, c; if (Prfact == 3) ini = ListV; if (Nb_cv < 4) { while ((c = *ini++) != 0) if (Tableau[c] == VIDE) *tab++ = c; *tab = 0; return ret; } x = 0; while ((c = *ini++) != 0) if (Tableau[c] == VIDE) { if (entour(c) != 0) *tab++ = c; else cp[x++] = c; } if (x != 0) for (c = 0; c < x; c++) *tab++ = cp[c]; *tab = 0; return ret; } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// short fpions_j(short *tab) { short c, n; NbreCoups2++; while (Tableau[c = *tab++] != VIDE) ; if ((n = nbprise(c, Adversaire)) != 0) return Resul - n - n - 1; if ((n = nbprise(c, Joueur)) != 0) return Resul + n + n + 1; if (Resul > 0) return Resul + 1; return Resul - 1; } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// short fpions_o(short *tab) { short c, n; NbreCoups2++; while (Tableau[c = *tab++] != VIDE) ; if ((n = nbprise(c, Joueur)) != 0) return Resul + n + n + 1; if ((n = nbprise(c, Adversaire)) != 0) return Resul - n - n - 1; if (Resul > 0) return Resul + 1; return Resul - 1; } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// short fscor_j(short *tab, short prev) { short *vid, *loc; short c, n, v, pass = -1; Prfact++; if (Prfact <= 6) loc = majlst2(tab, vid = T_v[Prfact], Adversaire); else loc = majlst(tab, vid = T_v[Prfact]); Alfbet[Prfact] = Alfbet[Prfact - 2]; while ((c = *loc++) != 0) { if ((n = joucoup(c, Adversaire)) == 0) continue; Tableau[c] = Adversaire; Nb_cv--; Resul -= n + n + 1; pass = 0; if (Nb_cv > 1) { v = fscor_o(vid, c); Prfact--; } else v = fpions_o(vid); Resul += n + n + 1; Tableau[c] = VIDE; if (rest_hor(n, Joueur) == 0) return 0; if (v < Alfbet[Prfact]) if ((Alfbet[Prfact] = v) <= Alfbet[Prfact - 1]) break; } if (pass == 0) return Alfbet[Prfact]; if (prev == 0) { if (Resul == 0) return 0; if (Resul > 0) return Resul + Nb_cv; return Resul - Nb_cv; } if (Nb_cv < 2) return fpions_o(vid); v = fscor_o(vid, 0); Prfact--; return v; } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// short fscor_o(short *tab, short prev) { short *vid, *loc; short c, n, v, pass = -1; Prfact++; if (Prfact <= 6) loc = majlst2(tab, vid = T_v[Prfact], Joueur); else loc = majlst(tab, vid = T_v[Prfact]); Alfbet[Prfact] = Alfbet[Prfact - 2]; while ((c = *loc++) != 0) { if ((n = joucoup(c, Joueur)) == 0) continue; Tableau[c] = Joueur; Nb_cv--; Resul += n + n + 1; pass = 0; if (Nb_cv > 1) { v = fscor_j(vid, c); Prfact--; } else v = fpions_j(vid); Resul -= n + n + 1; Tableau[c] = VIDE; if (rest_hor(n, Adversaire) == 0) return 0; if (v > Alfbet[Prfact]) if ((Alfbet[Prfact] = v) >= Alfbet[Prfact - 1]) break; } if (pass == 0) return Alfbet[Prfact]; if (prev == 0) { if (Resul == 0) return 0; if (Resul > 0) return Resul + Nb_cv; return Resul - Nb_cv; } if (Nb_cv < 2) return fpions_j(vid); v = fscor_j(vid, c); Prfact--; return v; } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// short fscor_1(short prem, short typ) { short *vid = T_v[1]; short c, n, v, x, pass, base = Repo1[prem]; pass = x = -1; Alfbet[1] = (typ == 0) ? 99 : 0; while ((c = Coup2[C2_ac = base + (++x)]) != 0) { n = prise(c, Adversaire); pass = 0; cre_vid(vid, base + x); if (Nb_cv < 1) v = Resul; else if (Nb_cv == 1) v = fpions_o(vid); else { v = fscor_o(vid, c); Prfact--; } if (restor(c, n, Joueur) == 0) return 0; if (v < Alfbet[1]) { Coup2[base] = c; if ((Alfbet[1] = v) <= Alfbet[0]) break; } } if (pass == 0) return Alfbet[1]; cre_vid(vid, base); if (Nb_cv < 1) return Resul; if (Nb_cv == 1) return fpions_o(vid); v = fscor_o(vid, c); Prfact--; return v; } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void fscor_0(short typ) { short c, n, v, x = -1; Prfact = 0; Alfbet[0] = typ; while ((c = Coup1[++x]) != 0) { n = prise(c, Joueur); Prfact++; v = fscor_1(x, typ); Prfact--; if (restor(c, n, Adversaire) == 0) return; if (v > Alfbet[0]) { Alfbet[0] = v; Coup1[0] = c; Repo1[0] = Repo1[x]; } if (typ == -99) if (Alfbet[0] > -2) return; if (Alfbet[0] > 63) return; } } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// short final_j(short *tab) { short c, n; if (Resul > 38) return 1; if (Resul < -38) return -1; while (Tableau[c = *tab++] != VIDE) ; if (Resul <= 0) { if (t_pris(c, Adversaire) != 0) return -1; if ((n = nbprise(c, Joueur)) != 0) return Resul + n + n + 1; return Resul; } if ((n = nbprise(c, Adversaire)) != 0) return Resul - n - n - 1; return 1; } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// short final_o(short *tab) { short c, n; if (Resul > 38) return 1; if (Resul < -38) return -1; while (Tableau[c = *tab++] != VIDE) ; if (Resul >= 0) { if (t_pris(c, Joueur) != 0) return 1; if ((n = nbprise(c, Adversaire)) != 0) return Resul - n - n - 1; return Resul; } if ((n = nbprise(c, Joueur)) != 0) return Resul + n + n + 1; return -1; } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// short fgp_j(short *tab, short prev) { short *vid, *loc; short c, n, v, pond, pass; Prfact++; pond = pass = 1; if (Prfact <= 6) loc = majlst2(tab, vid = T_v[Prfact], Adversaire); else loc = majlst(tab, vid = T_v[Prfact]); while ((c = *loc++) != 0) { if ((n = joucoup(c, Adversaire)) == 0) continue; Tableau[c] = Adversaire; Nb_cv--; Resul -= n + n + 1; pass = 0; if (Nb_cv > 1) { v = fgp_o(vid, c); Prfact--; } else v = final_o(vid); Resul += n + n + 1; Tableau[c] = VIDE; if (rest_hor(n, Joueur) == 0) return 0; if (v < pond) if ((pond = v) < 0) return -1; } if (pass == 0) return pond; if (prev == 0) return Resul; if (Nb_cv < 2) return final_o(vid); v = fgp_o(vid, 0); Prfact--; return v; } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// short fgp_o(short *tab, short prev) { short *vid, *loc; short c, n, v, pond, pass; Prfact++; pass = pond = -1; if (Prfact <= 6) loc = majlst2(tab, vid = T_v[Prfact], Joueur); else loc = majlst(tab, vid = T_v[Prfact]); while ((c = *loc++) != 0) { if ((n = joucoup(c, Joueur)) == 0) continue; Tableau[c] = Joueur; Nb_cv--; Resul += n + n + 1; pass = 0; if (Nb_cv > 1) { v = fgp_j(vid, c); Prfact--; } else v = final_j(vid); Resul -= n + n + 1; Tableau[c] = VIDE; if (rest_hor(n, Adversaire) == 0) return 0; if (v > pond) { if (Prfact == 2) Coup3[C2_ac] = c; if ((pond = v) > 0) return 1; } } if (pass == 0) return pond; if (prev == 0) return Resul; if (Nb_cv < 2) return final_j(vid); v = fgp_j(vid, 0); Prfact--; return v; } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// short fgp_1(short prem) { short *vid = T_v[1]; short c, n, v, x, pass, pond = 1, base = Repo1[prem]; pass = x = -1; while ((c = Coup2[C2_ac = base + (++x)]) != 0) { n = prise(c, Adversaire); pass = 0; cre_vid(vid, base + x); if (Nb_cv > 1) { v = fgp_o(vid, c); Prfact--; } else if (Nb_cv != 0) v = final_o(vid); else v = Resul; if (restor(c, n, Joueur) == 0) return 0; if (v < pond) { pond = v; if (x > 0) for (v = 0; v < 50; v++) { Coup2[base + v] = Coup2[C2_ac + v]; Coup3[base + v] = Coup3[C2_ac + v]; if (Coup2[base + v] == 0) v = 50; } x = 0; if (pond < 0) return -1; } } if (pass == 0) return pond; cre_vid(vid, base); if (Nb_cv < 2) { if (Nb_cv != 0) return final_o(vid); } else return Resul; v = fgp_o(vid, 0); Prfact--; return v; } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// short fgp_0(void) { short c, n, v, x, pond; Prfact = 0; pond = x = -1; while ((c = Coup1[++x]) != 0) { n = prise(c, Joueur); Prfact++; v = fgp_1(x); Prfact--; if (restor(c, n, Adversaire) == 0) return -2; if (v > pond) { pond = v; if (x > 0) for (v = x; v < 32; v++) { Coup1[v - x] = Coup1[v]; Repo1[v - x] = Repo1[v]; } x = 0; if (pond > 0) return 1; } } if (pond < 0) return -1; return 0; } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// short analyse(short niveau) { short temps_reflexion[] = { 0, 0, 2, 5, 10, 20, 50, 150, 300 }; // Temps de réflexion de chaque niveau en 10èmes de secondes short freq_affichage[] = { 0, 0, 25, 50, 100, 200, 200, 250, 500 }; // Nombre de coups entre deux rafraîchissements de la réflexion short Pnorm; short x, y; P_cp2 = Resul = NbreCoups2 = 0; for (x = 0; x < 20; x++) T_v[x] = Casvid + 60 * x; for (x = 0; x < 500; x++) Coup3[x] = 0; for (x = 10; x < 81; x++) if (Tableau[x] == Joueur) Resul++; else if (Tableau[x] == Adversaire) Resul--; for (x = Nb_cv = 0; x < 60; x++) if (Tableau[Ordre[x]] == VIDE) ListV[Nb_cv++] = Ordre[x]; ListV[Nb_cv] = 0; Phase = Nb_cv / 10; for (x = y = 0; ListV[x]; x++) if (t_pris(ListV[x], Joueur) != 0) Coup1[y++] = ListV[x]; Coup1[y] = 0; Prmax = 1; if ((Pnorm = Nb_cv - 9) < 7) if ((Pnorm = Nb_cv / 2) < 3) Pnorm = 3; TempsMax = 0; TempsMin = 9999; Freq = freq_affichage[niveau]; Compteur = CompteurTotal = CompteurPrecedent = temps_reflexion[niveau]; while (Prmax++ < Pnorm) { ProfMax = Prmax - 1; alfbet_0(); } if (Prmax < 90) { ProfMax = Nb_cv; for (x = 0; x < 30; x++) T_v[x] = Casvid + 30 * x; switch (fgp_0()) { case 1: if (GainSur == 0) { disp_msg(fr_eng("Je te tiens !", "I'm certain to"), fr_eng("", "win..."), Joueur); GainSur = 1; } fscor_0(0); break; case -1: fscor_0(-99); break; } } NbreCoups++; return Coup1[0]; }