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;
}