Skip to content

Instantly share code, notes, and snippets.

@Meithal
Created June 5, 2018 21:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Meithal/8ce036caf56c72291084c43fee774ae3 to your computer and use it in GitHub Desktop.
Save Meithal/8ce036caf56c72291084c43fee774ae3 to your computer and use it in GitHub Desktop.
puissance 4
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <time.h>
#define LARGEUR_DAMIER (7)
#define HAUTEUR_DAMIER (6)
#define LONGUEUR_DAMIER (LARGEUR_DAMIER * HAUTEUR_DAMIER)
#define LONGUEUR_VICTOIRE (4)
#define NOMBRE_JOUEURS (2)
#define CASE_VIDE ' '
#define CASE_JOUEUR_1 'X'
#define CASE_JOUEUR_2 'O'
#define NOMBRE_DIRECTIONS (8)
#define DIRECTION_NORD (0)
#define DIRECTION_NORD_EST (1)
#define DIRECTION_EST (2)
#define DIRECTION_SUD_EST (3)
#define DIRECTION_SUD (4)
#define DIRECTION_SUD_OUEST (5)
#define DIRECTION_OUEST (6)
#define DIRECTION_NORD_OUEST (7)
struct case_damier {
char contenu;
long index;
long ligne;
long colonne;
} damier[LARGEUR_DAMIER * HAUTEUR_DAMIER];
struct curseur {
struct case_damier * soi;
struct case_damier * directions[NOMBRE_DIRECTIONS];
} curseur;
struct joueur {
char humain;
char symbole;
int poids_colonne[LARGEUR_DAMIER];
} joueurs[NOMBRE_JOUEURS];
void assigne_curseur(struct case_damier * soi) {
for (int i = 0 ; i < NOMBRE_DIRECTIONS ; ++i)
curseur.directions[i] = NULL;
curseur.soi = soi;
if(soi) {
if (soi->ligne > 0)
curseur.directions[DIRECTION_NORD] = &damier[soi->index - LARGEUR_DAMIER];
if (soi->ligne > 0 && soi->colonne < LARGEUR_DAMIER - 1)
curseur.directions[DIRECTION_NORD_EST] = &damier[soi->index - LARGEUR_DAMIER + 1];
if (soi->colonne < LARGEUR_DAMIER - 1)
curseur.directions[DIRECTION_EST] = &damier[soi->index + 1];
if (soi->ligne < HAUTEUR_DAMIER - 1 && soi->colonne < LARGEUR_DAMIER - 1)
curseur.directions[DIRECTION_SUD_EST] = &damier[soi->index + LARGEUR_DAMIER + 1];
if (soi->ligne < HAUTEUR_DAMIER - 1)
curseur.directions[DIRECTION_SUD] = &damier[soi->index + LARGEUR_DAMIER];
if (soi->ligne < HAUTEUR_DAMIER - 1 && soi->colonne > 0)
curseur.directions[DIRECTION_SUD_OUEST] = &damier[soi->index + LARGEUR_DAMIER - 1];
if (soi->colonne > 0)
curseur.directions[DIRECTION_OUEST] = &damier[soi->index - 1];
if (soi->colonne > 0 && soi->ligne > 0)
curseur.directions[DIRECTION_NORD_OUEST] = &damier[soi->index - LARGEUR_DAMIER - 1];
}
}
int gagnant() {
char symbole;
for (int i = 0; i < LONGUEUR_DAMIER ; ++i) {
if (damier[i].contenu == CASE_VIDE) continue;
symbole = damier[i].contenu;
for (int direction = 0 ; direction < NOMBRE_DIRECTIONS ; direction ++) {
int longueur = 1;
assigne_curseur(&damier[i]);
while(curseur.soi->contenu == symbole) {
assigne_curseur(curseur.directions[direction]);
if(curseur.soi == NULL || curseur.soi->contenu != symbole)
break;
if(++longueur == LONGUEUR_VICTOIRE) {
if(symbole == CASE_JOUEUR_1) return 1;
if(symbole == CASE_JOUEUR_2) return 2;
}
}
}
}
return 0;
}
void afficher_numeros_ligne(void) {
for (int j = 1 ; j <= LARGEUR_DAMIER ; ++j) {
printf(" %d ", j);
}
putchar('\n');
}
void afficher_separation_horizontale(void) {
for (int j = 1 ; j <= LARGEUR_DAMIER ; ++j) {
printf("+---");
}
puts("+");
}
void afficher_damier() {
int ligne = 1;
for (typeof(LONGUEUR_DAMIER) i = 0 ; i < LONGUEUR_DAMIER ; i++) {
if (i == 0) {
afficher_numeros_ligne();
afficher_separation_horizontale();
}
printf("| %c ", damier[i].contenu);
if (((i + 1) % LARGEUR_DAMIER) == 0) {
puts("|");
afficher_separation_horizontale();
++ligne;
}
}
afficher_numeros_ligne();
}
void faire_tomber_curseur_jusque_case_vide(long colonne) {
assigne_curseur(&damier[colonne]);
while (curseur.directions[DIRECTION_SUD] != NULL
&& curseur.directions[DIRECTION_SUD]->contenu == CASE_VIDE) {
assigne_curseur(curseur.directions[DIRECTION_SUD]);
}
}
int longueur_suite(struct joueur * pJoueur) {
int longueur;
struct case_damier * position_initiale = curseur.soi;
int plus_grande_longueur = 1;
for (int direction = 0 ; direction < NOMBRE_DIRECTIONS ; direction++) {
assigne_curseur(position_initiale);
longueur = 1;
while(curseur.directions[direction] != NULL
&& curseur.directions[direction]->contenu == pJoueur->symbole) {
assigne_curseur(curseur.directions[direction]);
++longueur;
}
if (longueur > plus_grande_longueur) plus_grande_longueur = longueur;
}
return plus_grande_longueur;
}
void ponderer_colonnes(void) {
for(int i_joueur = 0 ; i_joueur < NOMBRE_JOUEURS ; i_joueur++) {
for(int i_colonne = 0 ; i_colonne < LARGEUR_DAMIER ; i_colonne++) {
faire_tomber_curseur_jusque_case_vide(i_colonne);
joueurs[i_joueur].poids_colonne[i_colonne] = longueur_suite(&joueurs[i_joueur]);
}
}
}
int choix_ia(struct joueur * pJoueur, struct joueur * pEnnemi) {
ponderer_colonnes();
int choix_ennemi = 0;
int poids_max_ennemi = 1;
for(int colonne = 0 ; colonne < LARGEUR_DAMIER ; ++colonne) {
if(pEnnemi->poids_colonne[colonne] > poids_max_ennemi)
poids_max_ennemi = pEnnemi->poids_colonne[colonne];
choix_ennemi = colonne;
} /* la case la plus attractive de l'ennemi */
int choix = 0;
int poids_max = 1;
for(int colonne = 0 ; colonne < LARGEUR_DAMIER ; ++colonne) {
if (pJoueur->poids_colonne[colonne] > poids_max) {
poids_max = pJoueur->poids_colonne[colonne];
choix = colonne;
}
if (pJoueur->poids_colonne[colonne] == poids_max) /* 1 chance sur 2 si proba egale*/
if ((rand() % 100) > 50)
choix = colonne;
} /* notre case la mieux */
if (poids_max_ennemi > poids_max || poids_max_ennemi == LONGUEUR_VICTOIRE)
choix = choix_ennemi; /* On contre l'ennemi */
return choix;
}
int main() {
char char_rec = '\0';
time_t the_time = time(NULL);
if (the_time == -1) {
puts("Cannot initialize the time");
return EXIT_FAILURE;
}
srand((unsigned int) the_time);
joueurs[0].symbole = CASE_JOUEUR_1;
joueurs[1].symbole = CASE_JOUEUR_2;
for (typeof(LONGUEUR_DAMIER) i = 0 ; i < LONGUEUR_DAMIER ; i++) {
damier[i].contenu = CASE_VIDE;
damier[i].index = i;
damier[i].colonne = i % LARGEUR_DAMIER;
damier[i].ligne = i / LARGEUR_DAMIER;
}
afficher_damier();
for (int i = 0 ; i < NOMBRE_JOUEURS ; ++i) {
do {
printf("Joueur %d humain ou ordinateur ? (H/O)\n> ", i + 1);
scanf(" %c", &char_rec);
if (tolower(char_rec) == 'h') {
joueurs[i].humain = '\1';
}
} while (tolower(char_rec) != 'h' && tolower(char_rec) != 'o');
}
struct joueur *joueur_actif = &joueurs[1];
struct joueur *joueur_ennemi = &joueurs[0];
long colonne_jouee;
int joueur_gagnant;
while(!(joueur_gagnant = gagnant())) {
joueur_ennemi = joueur_actif;
joueur_actif = (joueur_actif == &joueurs[0]) ? &joueurs[1] : &joueurs[0];
if (joueur_actif->humain) {
printf(
"Au joueur %ld (%c) de jouer (un chiffre entre 1 et 7)\n> ",
((joueur_actif - &joueurs[0]) + 1),
joueur_actif->symbole
);
while (1) {
scanf(" %c", &char_rec);
if (char_rec >= '1' && char_rec <= '7') {
colonne_jouee = strtol(&char_rec, NULL, 10);
if(damier[colonne_jouee -1].contenu == CASE_VIDE)
break;
else {
puts("Colonne remplie, veuillez en choisir une autre.");
}
} else {
puts("Chiffre invalide.");
}
}
} else {
colonne_jouee = choix_ia(joueur_actif, joueur_ennemi);
printf("L'ordinateur joue pour le joueur %ld (%c)\n",
((joueur_actif - &joueurs[0]) + 1),
joueur_actif->symbole
);
getchar();
}
faire_tomber_curseur_jusque_case_vide(colonne_jouee);
curseur.soi->contenu = joueur_actif->symbole;
afficher_damier();
}
printf("Le joueur %d (%c) a gagné", joueur_gagnant, joueur_actif->symbole);
return EXIT_SUCCESS;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment