miércoles, 3 de agosto de 2011

Tres en raya

He estado trabajando ayer y hoy en un juego de tres en raya. Ayer estuve desarrollando el algoritmo en pseudocódigo y, después de repasarlo y depurarlo un poco, hoy me he puesto a programar. Incluso así tuve algunos problemas a la hora de traducir el pseudocódigo a lenguaje C. Estos problemas fueron debidos al tiempo que llevo sin trabajar con este lenguaje y a las peculiaridades de los punteros (pueden ser un poco puñeteros). A continuación muestro el código del juego y después voy a jugar unas partidas.
#include <stdio.h>
#include <stdlib.h>

int main()
{
    char tablero[3][3] = {{'1','2','3'}, {'4','5','6'}, {'7','8','9'}};
    int vencedor = 0, casilla=0, fila=0, col=0;

    //Bucle principal de ejecución del programa
    while (hay_casillas_sin_marcar(tablero) && vencedor==0) {
        mostrar_tablero(tablero);
        printf("\nIntroduzca la casilla a marcar (1-9): ");
        scanf("%d",&casilla);

        //Traducimos el número de casilla a la fila y columna correspondiente
        if (casilla==1) { fila=0; col=0;}
        if (casilla==2) { fila=0; col=1;}
        if (casilla==3) { fila=0; col=2;}
        if (casilla==4) { fila=1; col=0;}
        if (casilla==5) { fila=1; col=1;}
        if (casilla==6) { fila=1; col=2;}
        if (casilla==7) { fila=2; col=0;}
        if (casilla==8) { fila=2; col=1;}
        if (casilla==9) { fila=2; col=2;}

        if (!casilla_marcada(fila,col,tablero)) {

            marcar_casilla(fila,col,0,tablero);
            if (tres_en_raya(tablero)) {
                vencedor=1;  //gana el usuario
            }
            else {
                marcar_casilla_ordenador(tablero);
                if (tres_en_raya(tablero))
                    vencedor=2;  //gana el ordenador
            }
        }
    }

    if (vencedor==0) printf("No hay ganador\n");
    if (vencedor==1) printf("El ganador es el usuario\n");
    if (vencedor==2) printf("El ganador es el ordenador\n");

    return 0;
}

//Función HAY_CASILLAS_SIN_MARCAR()
int hay_casillas_sin_marcar(char (*tablero)[3][3]) {
    int i=0, j=0;   //indice de fila y columna

    for (i=0; i<3; i++) {
        for (j=0; j<3; j++) {
            if (((*tablero)[i][j]!='X') && ((*tablero)[i][j]!='O'))
                return 1;   //devolvemos verdadero
        }
    }
    return 0;  //devolvemos falso
}

//Función MOSTRAR_TABLERO()
void mostrar_tablero(char (*tablero)[3][3]) {
    int i=0, j=0;

    for (i=0; i<3; i++) {
        for (j=0; j<3; j++) {
            printf("%c  ", (*tablero)[i][j]);
        }
        printf("\n");   //pasamos a la siguiente fila
    }
}

//Función CASILLA_MARCADA(ENTERO fila, ENTERO columnma)
int casilla_marcada(int fila, int columna, char (*tablero)[3][3]) {

    if ((*tablero)[fila][columna] == 'X' || (*tablero)[fila][columna] == 'O') {
        return 1;
    }
    else {
        return 0;
    }
}

//Función MARCAR_CASILLA(ENTERO casilla, ENTERO jugador)
void marcar_casilla(int fila, int columna, int jugador, char (*tablero)[3][3]) {

    //jugador: 0->usuario, 1->ordenador
    if (jugador==0) { //jugador=usuario
        (*tablero)[fila][columna]='X';
    }
    if (jugador==1) {  //jugador=ordenador
        (*tablero)[fila][columna]='O';
        printf("jugador==1 (ordenador) casilla: (%d,%d)\n",fila,columna);
    }
}

//Función ENTERO TRES_EN_RAYA()
int tres_en_raya(char (*tablero)[3][3]) {
    int i=0, j=0;

    //Comprobamos todas las filas
    for (i=0; i<3; i++) {
        if (((*tablero)[i][0]==(*tablero)[i][1]) && ((*tablero)[i][1]==(*tablero)[i][2])) {
            return 1;
        }
    }
    //Comprobamos las columnas
    for (j=0; j<3; j++) {
        if (((*tablero)[0][j]==(*tablero)[1][j]) && ((*tablero)[1][j]==(*tablero)[2][j])) {
            return 1;
        }
    }
    //Comprobamos diagonales
    if ((*tablero)[0][0]==(*tablero)[1][1] && (*tablero)[1][1]==(*tablero)[2][2]) {
        return 1;
    }
    if ((*tablero)[0][2]==(*tablero)[1][1] && (*tablero)[1][1]==(*tablero)[2][0]) {
        return 1;
    }
    return 0;  //si no se cumple ninguna de las condiciones anteriores no hay tres en raya
}

//Función MARCAR_CASILLA_ORDENADOR()
void marcar_casilla_ordenador(char (*tablero)[3][3]) {
    int i=0, j=0, marcada=0;

    // //////       /////////    ////////////   /////////////  //////
    //Comprobamos si el ordenador tiene opción de hacer tres en raya
    //   /////////  /////////  ////////   //////  //////   //////////
    //Para cada fila
    for (i=0; i<3; i++) {
        if (((*tablero)[i][0]=='O') && ((*tablero)[i][1]=='O') && (isdigit((*tablero)[i][2]))) {
            marcar_casilla(i,2,1,tablero);
            return;
        }
         if (((*tablero)[i][1]=='O') &&((*tablero)[i][2]=='O') && (isdigit((*tablero)[i][0]))) {
            marcar_casilla(i,0,1,tablero);
            return;
        }
        if (((*tablero)[i][0]=='O') &&((*tablero)[i][2]=='O') && (isdigit((*tablero)[i][1]))) {
            marcar_casilla(i,1,1,tablero);
            return;
        }
   }
   //Para cada columna
     for (j=0; j<3; j++) {
        if (((*tablero)[0][j]=='O') &&((*tablero)[1][j]=='O') && (isdigit((*tablero)[2][j]))) {
            marcar_casilla(2,j,1,tablero);
            return;
        }
        if (((*tablero)[1][j]=='O') &&((*tablero)[2][j]=='O') && (isdigit((*tablero)[0][j]))) {
            marcar_casilla(0,j,1,tablero);
            return;
        }
        if (((*tablero)[0][j]=='O') &&((*tablero)[2][j]=='O') && (isdigit((*tablero)[1][j]))) {
            marcar_casilla(1,j,1,tablero);
            return;
        }
    }
    //Diagonales
        if (((*tablero)[0][0]=='O') && ((*tablero)[1][1]=='O') && (isdigit((*tablero)[2][2]))) {
        marcar_casilla(2,2,1,tablero);
        return;
    }
    if (((*tablero)[1][1]=='O') && ((*tablero)[2][2]=='O') && (isdigit((*tablero)[0][0]))) {
        marcar_casilla(0,0,1,tablero);
        return;
    }
    if (((*tablero)[0][0]=='O') && ((*tablero)[2][2]=='O') && (isdigit((*tablero)[1][1]))) {
        marcar_casilla(1,1,1,tablero);
        return;
    }
    //
    if (((*tablero)[0][2]=='O') && ((*tablero)[1][1]=='O') && (isdigit((*tablero)[2][0]))) {
        marcar_casilla(2,0,1,tablero);
        return;
    }
    if (((*tablero)[1][1]=='O') && ((*tablero)[2][0]=='O') && (isdigit((*tablero)[0][2]))) {
        marcar_casilla(0,2,1,tablero);
        return;
    }
    if (((*tablero)[0][2]=='O') && ((*tablero)[2][0]=='O') && (isdigit((*tablero)[1][1]))) {
        marcar_casilla(1,1,1,tablero);
        return;
    }


    // //  //  //  //  //  //  //  //  //  //  //  //  //  //  //  //  //
    //Comprobamos filas para ver si hay 2 casillas marcadas por el usuario
    // //  //  //  //  //  //  //  //  // //  //  //  //  //  //  //  //
    for (i=0; i<3; i++) {
        if (((*tablero)[i][0]=='X') &&((*tablero)[i][1]=='X') && (isdigit((*tablero)[i][2]))) {
            marcar_casilla(i,2,1,tablero);
            return;
        }
        if (((*tablero)[i][1]=='X') &&((*tablero)[i][2]=='X') && (isdigit((*tablero)[i][0]))) {
            marcar_casilla(i,0,1,tablero);
            return;
        }
        if (((*tablero)[i][0]=='X') &&((*tablero)[i][2]=='X') && (isdigit((*tablero)[i][1]))) {
            marcar_casilla(i,1,1,tablero);
            return;
        }
    }
    //Comprobamos columnas para ver si alguna tiene 2 casillas marcadas por el usuario
    for (j=0; j<3; j++) {
        if (((*tablero)[0][j]=='X') &&((*tablero)[1][j]=='X') && (isdigit((*tablero)[2][j]))) {
            marcar_casilla(2,j,1,tablero);
            return;
        }
        if (((*tablero)[1][j]=='X') &&((*tablero)[2][j]=='X') && (isdigit((*tablero)[0][j]))) {
            marcar_casilla(0,j,1,tablero);
            return;
        }
        if (((*tablero)[0][j]=='X') &&((*tablero)[2][j]=='X') && (isdigit((*tablero)[1][j]))) {
            marcar_casilla(1,j,1,tablero);
            return;
        }
    }
    //Comprobamos diagonales para ver si alguna tiene 2 casillas marcadas por el usuario
    if (((*tablero)[0][0]=='X') && ((*tablero)[1][1]=='X') && (isdigit((*tablero)[2][2]))) {
        marcar_casilla(2,2,1,tablero);
        return;
    }
    if (((*tablero)[1][1]=='X') && ((*tablero)[2][2]=='X') && (isdigit((*tablero)[0][0]))) {
        marcar_casilla(0,0,1,tablero);
        return;
    }
    if (((*tablero)[0][0]=='X') && ((*tablero)[2][2]=='X') && (isdigit((*tablero)[1][1]))) {
        marcar_casilla(1,1,1,tablero);
        return;
    }
    //
    if (((*tablero)[0][2]=='X') && ((*tablero)[1][1]=='X') && (isdigit((*tablero)[2][0]))) {
        marcar_casilla(2,0,1,tablero);
        return;
    }
    if (((*tablero)[1][1]=='X') && ((*tablero)[2][0]=='X') && (isdigit((*tablero)[0][2]))) {
        marcar_casilla(0,2,1,tablero);
        return;
    }
    if (((*tablero)[0][2]=='X') && ((*tablero)[2][0]=='X') && (isdigit((*tablero)[1][1]))) {
        marcar_casilla(1,1,1,tablero);
        return;
    }

    //Si la casilla central está vacía la marcamos
    if ((*tablero)[1][1]=='5') {
        marcar_casilla(1,1,1,tablero);
    } else {
        i=0;  //fila
        j=0;  //columna

        //Buscamos una casilla sin marcar y la marcamos
        while (!marcada) {
            if (isdigit((*tablero)[i][j])) {
                (*tablero)[i][j]='O';
                marcada=1;
            }
                j++;
                if(j%3 == 0) {
                    i++;
                    j=j%3;
                }
        }
    }

    return;
}

No hay comentarios:

Publicar un comentario