Code Vonc

Tourni4

v 1.0

Win

TéléchargerDownload
Faire un donMake a donation
CommentairesComments

Jeu Tourni4 réalisé en C, en mode console.

Projet réalisé avec Cédric Bitsch.



Codes sourcesSources code

main.c

#include <stdio.h>
#include <stdlib.h>

void initJeu(int*,int);
int XYversI(int,int,int);
void IversXY(int,int*,int*,int);
void afficheLigne(int);
void affichageJeu(int*,int,int);
void affichageCoups(int,int);
int* genereGrille(int*, int*, int*, int*);
void ajouterPion(int*, int*, int, int, int);
void tourne180(int*, int*, int, int);
void tourne90(int*, int*, int, int, int);
void tournerJeu(int*, int*, int, int, char, int);
int verifAction(char, char*, int*);
int verifJeuPlein(int*, int);
int verifJeuGagneHoriz(int*, int, int, int, int, int);
int verifJeuGagneVerti(int*, int, int, int, int, int);
int verifJeuGagneDiagG(int*, int, int, int, int, int);
int verifJeuGagneDiagD(int*, int, int, int, int, int);
int verifJeuGagne(int*, int, int, int);
int verifJeu(int*, int, int, int, int, int);

void initJeu(int* jeu, int jeuTaille) {
    int i;
    for (i = 0 ; i < jeuTaille ; i++) {
        jeu[i] = 0;
    }
}

int XYversI(int x, int y, int l) {
    if (x < 0) x += l * (x/l+1);
    if (y < 0) y += l * (y/l+1);
    x = x % l;
    y = y % l;
    return x + y * l;
}

void IversXY(int i, int* x, int* y, int l) {
    *x = i % l;
    *y = i / l;
}

void afficheLigne(int tailleLigne) {
    int i;
    printf("\n-");
    for (i = 0 ; i < tailleLigne ; i++) {
        printf("----");
    }
}

void afficheLigne2(int tailleLigne) {
    int i;
    printf("\n=");
    for (i = 0 ; i < tailleLigne ; i++) {
        printf("====");
    }
}

void affichageJeu(int* jeu, int jeuTaille, int tailleLigne) {
    int i;
    if (tailleLigne == 0) return;

    printf("\n");
    afficheLigne(tailleLigne);
    printf("\n");

    for (i = 0 ; i < tailleLigne ; i++) {
        printf("| %d ", i);
        if (i == tailleLigne - 1) {
        printf("|");
        }
    }

    afficheLigne2(tailleLigne);

    printf("\n");
    for (i = 0 ; i < jeuTaille ; i++) {

        if (jeu[i] == 0)
            printf("|   ");
        else printf("| %d ", jeu[i]);
        /*else if (jeu[i] == 1)
            printf("| X ");
        else if (jeu[i] == 2)
            printf("| O ");*/

        if ((i+1) % tailleLigne == 0) {
            printf("|");
            afficheLigne(tailleLigne);
            printf("\n");
        }

    }
}

void affichageCoups(int tailleLigne, int joueurCourant) {
    printf("\n C'est au joueur %d de jouer", joueurCourant+1);
    printf("\n num colonne : Ajouter un pion");
    printf("\n h : Tourner dans le sens horaire");
    printf("\n a : Tourner dans le sens anti-horaire");
    printf("\n d : Renverser");
}

int* genereGrille(int* jeuTaille, int* tailleLigne, int* joueurCourant, int* nbJoueur) {
    int saisie;
    int *jeu;

    do {
        printf("\n Saisir le nombre de joueurs superieur ou egal a 2 : ");
        scanf("%d", &saisie);
    }
    while (saisie < 2);
    *nbJoueur = saisie;

    printf("\n");

    do {
        printf("\n Saisir une grille entre 5 et 10 : ");
        scanf("%d", &saisie);
    }
    while (saisie < 5 || saisie > 10);

    *tailleLigne = saisie;
    *jeuTaille = saisie * saisie;

    jeu = malloc(sizeof(int) * *jeuTaille);
    initJeu(jeu, *jeuTaille);

    *joueurCourant = 0;

    return jeu;
}

void ajouterPion(int* jeu, int* joueurCourant, int tailleLigne, int colonne, int nbJoueur) {
    int i, caze;

    while(colonne < 0 || colonne >= tailleLigne) {
        printf("\n\n Choisir une colonne entre 0 et %d : ", tailleLigne-1);
        scanf("%d", &colonne);
    }

    i = tailleLigne - 1;
    caze = colonne + tailleLigne * i;
    while(jeu[caze] != 0) {
        i--;
        if (i == -1) {
            printf("\n Colonne pleine.\n\n");
            system("pause");
            return;
        }
        caze = colonne + tailleLigne * i;
    }

    jeu[caze] = *joueurCourant + 1;
    //*joueurCourant = !*joueurCourant;
    *joueurCourant = (*joueurCourant+1) % nbJoueur;

}

void tourne180(int* jeu, int* jeuTemp, int tailleLigne, int jeuTaille) {
    int i, n, x, y;

    int* nbJetons = malloc(sizeof(int) * tailleLigne);
    if (nbJetons == NULL) return;
    initJeu(nbJetons, tailleLigne);

    // Compte le nb de jetons par colonne
    for (i = 0 ; i < jeuTaille ; i++) {
        n = i - (i % tailleLigne);
        if (jeu[i] != 0) nbJetons[i % tailleLigne]++;
    }

    // Renverse
    for (i = 0 ; i < jeuTaille ; i++) {
        n = tailleLigne - nbJetons[i % tailleLigne]; // Nb de place libre

        IversXY(i, &x, &y, tailleLigne);
        x = tailleLigne - x - 1; // Symétrie X
        y = tailleLigne - y - 1 + n; // Symétrie Y + nb de places libres

        jeuTemp[XYversI(x, y, tailleLigne)] = jeu[i];
    }

    free(nbJetons);
}

void tourne90(int* jeu, int* jeuTemp, int tailleLigne, int jeuTaille, int inv) {
    int i, nbJeton = 0, ligne = 0, iMin = 0, iMax = jeuTaille, iPlus = 1, iMod = 1;

    if (inv) {
        iMin = jeuTaille - 1;
        iMax = 0;
        iPlus = -1;
        iMod = 0;
    }

    for (i = iMin ; i != iMax ; i += iPlus) {
        if (jeu[i] != 0) {
            nbJeton++;
            jeuTemp[ligne + tailleLigne * (tailleLigne - nbJeton)] = jeu[i];
        }
        if ((i+iMod) % tailleLigne == 0) {
            nbJeton = 0;
            ligne++;
        }
    }
}

void tournerJeu(int* jeu, int* joueurCourant, int tailleLigne, int jeuTaille, char action, int nbJoueur) {
    int *jeuTemp, i;

    jeuTemp = malloc(sizeof(int) * jeuTaille);
    if (jeuTemp == NULL) return;

    initJeu(jeuTemp, jeuTaille);

    if (action != 'd')
        tourne90(jeu, jeuTemp, tailleLigne, jeuTaille, action=='h');
    else
        tourne180(jeu, jeuTemp, tailleLigne, jeuTaille);

    initJeu(jeu, jeuTaille);

    for (i = 0 ; i < jeuTaille ; i++) {
        jeu[i] = jeuTemp[i];
    }

    //*joueurCourant = !*joueurCourant;
    *joueurCourant = (*joueurCourant+1) % nbJoueur;

    free(jeuTemp);
    return;
}

int verifAction(char action, char* ancAction, int* nbActionPiv) {
    if (action == *ancAction) {
        printf("\n Vous ne pouvez jouer l'action inverse du joueur precedent\n\n");
        system("pause");
        return 0;
    }

    (*nbActionPiv)++;
    if (*nbActionPiv == 8) {
        printf("\n Vous ne pouvez jouer 8 rotations d'affile\n\n");
        return 0;
    }

    if (action == 'h') *ancAction = 'a';
    else if (action == 'a') *ancAction = 'h';
    else *ancAction = 'd';
    return 1;
}

int verifJeuPlein(int* jeu, int jeuTaille) {
    int i;
    for (i = 0 ; i < jeuTaille ; i++) {
        if (jeu[i] == 0) return 0;
    }
    return 1;
}

int verifJeuGagneHoriz(int* jeu, int tailleLigne, int x, int y, int val, int verifMax) {
    int i, j;
    if (x < verifMax-1) return 0;
    for (i = 0 ; i < verifMax-1 ; i++) {
        x--;
        j = XYversI(x, y, tailleLigne); // On vérifie la case X à gauche
        if (jeu[j] != val) return 0;
    }
    return val; // Si on a pas cassé la boucle, c'est qu'il a gagné
}

int verifJeuGagneVerti(int* jeu, int tailleLigne, int x, int y, int val, int verifMax) {
    int i, j;
    if (y < verifMax-1) return 0;
    for (i = 0 ; i < verifMax-1 ; i++) {
        y--;
        j = XYversI(x, y, tailleLigne); // On vérifie la case Y en haut
        if (jeu[j] != val) return 0;
    }
    return val;
}

int verifJeuGagneDiagG(int* jeu, int tailleLigne, int x, int y, int val, int verifMax) {
    int i, j;
    if (x < verifMax-1) return 0;
    if (y < verifMax-1) return 0;
    for (i = 0 ; i < verifMax-1 ; i++) {
        x--;
        y--;
        j = XYversI(x, y, tailleLigne); // On vérifie la case en haut à gauche
        if (jeu[j] != val) return 0;
    }
    return val;
}

int verifJeuGagneDiagD(int* jeu, int tailleLigne, int x, int y, int val, int verifMax) {
    int i, j;
    if (tailleLigne - x < verifMax) return 0; // Faut au moins verifMax cases libres à droite
    if (y < verifMax-1) return 0;
    for (i = 0 ; i < verifMax-1 ; i++) {
        x++;
        y--;
        j = XYversI(x, y, tailleLigne); // On vérifie la case en haut à droite
        if (jeu[j] != val) return 0;
    }
    return val;
}

int verifJeuGagne(int* jeu, int jeuTaille, int tailleLigne, int nbJoueur) {
    int i, verifMax = 4, x, y, res = 0, nbGagne = 0, jGagne = -1;
    int* jxGagne;

    jxGagne = malloc(nbJoueur * sizeof(int));
    if (jxGagne == NULL) return 0;
    initJeu(jxGagne, nbJoueur);

    for (i = jeuTaille-1 ; i >= 0 ; i--) { // On part d'en bas à droite
        if (!jeu[i]) continue;
        IversXY(i, &x, &y, tailleLigne);

        res = verifJeuGagneHoriz(jeu, tailleLigne, x, y, jeu[i], verifMax);
        if (res) jxGagne[res-1] = 1;
        //if (res == 1) j1Gagne = 1;
        //else if (res == 2) j2Gagne = 1;

        res = verifJeuGagneVerti(jeu, tailleLigne, x, y, jeu[i], verifMax);
        if (res) jxGagne[res-1] = 1;

        res = verifJeuGagneDiagG(jeu, tailleLigne, x, y, jeu[i], verifMax);
        if (res) jxGagne[res-1] = 1;

        res = verifJeuGagneDiagD(jeu, tailleLigne, x, y, jeu[i], verifMax);
        if (res) jxGagne[res-1] = 1;
    }

    for (i = 0 ; i < nbJoueur ; i++) {
        if (jxGagne[i]) {
            nbGagne++;
            jGagne = i;
        }
    }
    free(jxGagne);

    if (nbGagne > 1) return 3;
    if (jGagne != -1) return jGagne + 1;

    return 0;
}

int verifJeu(int* jeu, int joueurCourant, int tailleLigne, int jeuTaille, int nbActionPiv, int nbJoueur) {
    int gagne = 0;
    gagne = verifJeuGagne(jeu, jeuTaille, tailleLigne, nbJoueur);

    if (nbActionPiv == 8 || verifJeuPlein(jeu, jeuTaille) || gagne == 3) {
        printf("\n Match nul\n\n");
        return 1;
    }

    if (gagne) {
        printf("\n Joueur %d a gagne !\n\n", gagne);
        return 1;
    }

    return 0;
}

int main()
{
    char action = 0, ancAction = 0;
    int nbActionPiv = 0;
    int *jeu = NULL;
    int jeuTaille = 0, tailleLigne = 0, joueurCourant = 0, jeuFini = 0;
    int nbJoueur = 2;

    while (action != 'q') {
        printf(" --------------------------------------");
        printf("\n|       Bienvenue dans Tourni4        |");
        printf("\n --------------------------------------");
        printf("\n\n Menu :");
        printf("\n c : Commencer une partie");
        printf("\n q : Quitter");
        printf("\n");

        affichageJeu(jeu, jeuTaille, tailleLigne);

        if (jeu) {
            jeuFini = verifJeu(jeu, joueurCourant, tailleLigne, jeuTaille, nbActionPiv, nbJoueur);
            if (!jeuFini) affichageCoups(tailleLigne, joueurCourant);
        }

        // Commandes
        printf("\n Action : ");
        scanf(" %c", &action);

        if (action == 'c') jeu = genereGrille(&jeuTaille, &tailleLigne, &joueurCourant, &nbJoueur);

        if (jeu && !jeuFini) {
            if (action >= '0' && action <= '9') {
                ajouterPion(jeu, &joueurCourant, tailleLigne, (int)(action - '0'), nbJoueur);
                ancAction = 0;
                nbActionPiv = 0;
            }

            if (action == 'h' || action == 'a' || action == 'd') {
                if (verifAction(action, &ancAction, &nbActionPiv)) tournerJeu(jeu, &joueurCourant, tailleLigne, jeuTaille, action, nbJoueur);
            }

        }

        system("cls");

    }

    printf("\n\n Merci d'avoir joue a Tourni4 !\n\n");

    if (jeu) free(jeu);
    return 0;
}