/* TP semaine 26 2003 - 2004
H. Mélot
*/
/* Beaucoup d'améliorations possibles:
- modifier la profondeur en fonction du nombre de cases
qui restent à jouer, pour que ce ne soit pas trop lent au début
- utiliser symétries (nottament pour le premier coup)
- ...
*/
#include <stdio.h>
#define N 8
int MAX_PROF;
void initialisation(char tab[N][N], int n)
{
int i,j;
for (i = 0; i < n; i++)
for (j = 0; j < n; j++)
tab[i][j] = ' ';
}
void affichage(char tab[N][N],int n)
{
int i,j;
printf("\n ");
for (i = 0; i < n; i ++)
printf("%d ", i);
printf("\n ");
for (i = 0; i < n; i ++)
printf("___ ");
for (i = 0; i < n; i ++)
{
printf("\n |");
for (j = 0; j < n; j++)
printf(" |");
printf("\n %d |", i);
for (j = 0; j < n; j ++)
printf(" %c |", tab[i][j]);
printf("\n |");
for (j = 0; j < n; j++)
printf("___|");
}
printf("\n");
}
void lecture_case(char tab[N][N], int n, int* ligne, int* colonne, int joueur)
{
int ok = 0;
*ligne = -1;
*colonne = -1;
printf("Joueur %d. Entrez la case a jouer :\n", joueur);
do {
while (((*ligne) < 0) || ((*ligne) >= n))
{
printf("Ligne (0 -- %d) ? ", n-1);
scanf("%d", ligne);
}
while ((*colonne < 0) || (*colonne >= n))
{
printf("Colonne (0 -- %d) ? ", n-1);
scanf("%d", colonne);
}
if (tab[*ligne][*colonne] != ' ')
{
printf("Choisissez une autre case! Celle-ci est prise.\n");
*ligne = -1; *colonne = -1;
}
else
ok = 1;
} while (ok == 0);
}
void mise_a_jour(char tab[N][N], int ligne, int colonne, int joueur)
{
if (joueur == 1)
tab[ligne][colonne] = 'X';
else
tab[ligne][colonne] = 'O';
}
int verification(char tab[N][N], int n, int joueur, int l, int c)
{
int i;
int vl = 1;
int vc = 1;
int vd1 = 1;
int vd2 = 1;
char ch;
if (joueur == 1)
ch = 'X';
else
ch = 'O';
for (i = 0; i < n; i ++)
{
if (tab[l][i] != ch)
vl = 0;
if (tab[i][c] != ch)
vc = 0;
if (tab[i][i] != ch)
vd1 = 0;
if (tab[i][n-i-1] != ch)
vd2 = 0;
}
if ((vl == 1) || (vc == 1) || (vd1 == 1) || (vd2 == 1))
return joueur;
else
return 0;
}
void change_joueur(int *joueur)
{
if ((*joueur) == 1)
*joueur = 2;
else
*joueur = 1;
}
int exaequo(char tab[N][N],int n)
{
int i,j;
for (i = 0; i < n; i ++)
for (j = 0; j < n; j ++)
if (tab[i][j] == ' ')
return 0;
return 1;
}
double search(char tab[N][N], int n, int l, int c, int joueur, int prof)
{
int i,j;
double sum = 0;
mise_a_jour(tab,l,c,joueur);
if (verification(tab,n,joueur,l,c))
{
if (joueur == 2)
sum += 1. / (double) prof;
else
sum -= 1. / (double) prof;
}
else if (prof < MAX_PROF)
{
change_joueur(&joueur);
for (i = 0; i < n; i++)
for (j = 0; j < n; j++)
if (tab[i][j] == ' ')
sum += search(tab,n,i,j,joueur,prof+1);
}
tab[l][c] = ' ';
return sum;
}
/*
void choix_ordi(char tab[N][N], int n, int* ligne, int* colonne)
{
int best_l = -1, best_c = -1;
double best_sum = -99999;
double sum;
int i,j;
printf("L'ordinateur calcule son prochain coup...\n");
/* Enlever les commentaires pour afficher les sommes calculées
par l'ordinateur
// printf("Sum:\n");
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
{
if (tab[i][j] == ' ')
{
sum = search(tab,n,i,j,2,1);
// printf("%g, ",sum);
if (best_sum < sum)
{
best_sum = sum;
best_l = i;
best_c = j;
}
}
// else
// printf("X, ");
}
//printf("\n");
}
*ligne = best_l;
*colonne = best_c;
printf("--> case (%d,%d)\n",*ligne,*colonne);
}
int main()
{
int n;
char grille[N][N];
int joueur = 1;
int lig, col;
int egal = 0;
int gagne = 0;
int mode;
printf("OXO - Bienvenue.\n");
do {
printf("Choisissez la taille de la grille (2 -- 7) : ");
scanf("%d",&n);
} while (n < 2 || n > 10);
// choix de la profondeur (pour que le jeu ne soit pas trop lent)
switch (n) {
case 2 : MAX_PROF = 4; break;
case 3 : MAX_PROF = 9; break;
case 4 : MAX_PROF = 7; break;
case 5 : MAX_PROF = 5; break;
}
do {
printf("Choisissez votre mode de jeu :\n");
printf("1. Joueur vs Joueur\n");
printf("2. Joueur vs Ordinateur\n");
scanf("%d",&mode);
} while (mode < 1 || mode > 2);
if (mode == 2)
{
do {
printf("Qui commence ?\n");
printf("1. Joueur\n");
printf("2. Ordinateur\n");
scanf("%d",&joueur);
} while (joueur < 1 || joueur > 2);
}
initialisation(grille,n);
affichage(grille,n);
do {
if (mode == 2 && joueur == 2)
choix_ordi(grille,n,&lig,&col);
else
lecture_case(grille,n,&lig,&col,joueur);
mise_a_jour(grille,lig,col,joueur);
affichage(grille,n);
gagne = verification(grille,n,joueur,lig,col);
if (gagne == 0)
egal = exaequo(grille,n);
change_joueur(&joueur);
} while ((egal == 0) && (gagne == 0));
if (egal == 1)
printf("\nEgalite!\n");
else
printf("\nLe joueur %d a gagne la partie!\n", gagne);
return 0;
}