Juego 4 en linea. Ayuda!!!

Iniciado por mathias_vg, 3 Junio 2013, 16:47 PM

0 Miembros y 1 Visitante están viendo este tema.

rir3760

Algunos comentarios:

scanf(" \n%d",&dim);
En la cadena de formato " \n%d" no es necesario utilizar " \n" ya que la función lo primero que hace es descartar el espacio blanco (tabulador, avance de linea, etc). Solo es necesario cuando se utilizan los especificadores "%c" y "%[]" ya que con ellos el descarte no sucede.

scanf (" \n%d",&dim);

/* ... */

char matriz[dim][dim];

Si van a utilizar un array declarado en esa forma hay que asegurarse de que el compilador soporte el estándar C99 y se compile en ese modo (a veces sucede).

char matriz[dim][dim];

/* ... */

for (i = 1; i <= dim; i++){
   for (j = 1; j <= dim; j++){
      matriz[i][j] = '.';
      printf("%c ", matriz[i][j]);
   }
   
   printf("\n");
}

En C y C los indices de los arrays inician en 0 y terminan en N-1 donde N es el numero de elementos. Hay que cambiar el par de bucles a:
char matriz[dim][dim];

/* ... */

for (i = 0; i < dim; i++){
   for (j = 0; j < dim; j++){
      matriz[i][j] = '.';
      fputs(". ", stdout); /* Imprime ". " en la salida estandar */
   }
   
   printf("\n");
}


Un saludo
C retains the basic philosophy that programmers know what they are doing; it only requires that they state their intentions explicitly.
--
Kernighan & Ritchie, The C programming language

KaL3o

hay varios apartes que se repiten, seria bueno utilizar funciones, reduciriaas varias lineas de codigo

salu2 :)
Todos los caminos se vuelven a juntar. Pero nunca de la misma forma.

leosansan

#22
Cita de: rir3760 en  7 Junio 2013, 02:30 AM
Algunos comentarios:
........................................
Si van a utilizar un array declarado en esa forma hay que asegurarse de que el compilador soporte el estándar C99 y se compile en ese modo (a veces sucede).

Yo al menos llevo un tiempito usándolos en el Code::Blocks sin problemas.

Cita de: rir3760 en  7 Junio 2013, 02:30 AM
char matriz[dim][dim];

/* ... */

for (i = 1; i <= dim; i++){
  for (j = 1; j <= dim; j++){
     matriz[i][j] = '.';
     printf("%c ", matriz[i][j]);
  }
 
  printf("\n");
}

En C y C los indices de los arrays inician en 0 y terminan en N-1 donde N es el numero de elementos. Hay que cambiar el par de bucles a:
char matriz[dim][dim];

/* ... */

for (i = 0; i < dim; i++){
  for (j = 0; j < dim; j++){
     matriz[i][j] = '.';
     fputs(". ", stdout); /* Imprime ". " en la salida estandar */
  }
 
  printf("\n");
}


Un saludo

Sí, estoy de acuerdo contigo. Pero yo lo estoy haciendo "a conciencia", puesto que las líneas de i=0 y j=0 se rellenarán para la numeración de las casillas.

Y la dimensión de la matriz en mi último post ya estaba corregida a dim+1. De todas formas, gracias nuevamente por la atención prestada.

Saluditos! .... ..

mathias_vg

Buenas! finalmente luego de unas cuantas horas podido hacer el juego. Lo posteo abajo para que me puedan corregir algunas cosas las cuales yo no me doy cuenta debido a que soy bastante nuevo en esto.

leosansan muchas gracias, me ha sido de gran ayuda tus consejos.


#include <stdio.h>
#include <stdlib.h>
#define DIM 16
int inicializar_tablero(char tablero[][DIM],int);
int juegan_O_(char tabla[][DIM],int,int);
int juegan_X_(char tablero[][DIM],int,int);
int main()
{
    int n=0,i,j,x,resto=1,k=0,jugador,partida,victoria=0;
    char d;
    printf("\n\n\n     JUEGO CONECTA CUATRO\n\n\n\n\n\n\n");
    printf("       Nueva partida (S/N): ");
    do
    {
        scanf("%c",&d);
        system("cls");
        if (d=='n' || d=='N')
        {
            return 1;
        }
        if (d!='s' && d!='S')
            printf("\nOpcion incorrecta. Elija: s / n  ");
    }while (d!='s' && d!='S');
    volver:
    printf("\n\nIngresa la dimension del tablero de juego(4-15): ");
    do
    {
        scanf (" %d",&x);
        system("cls");
        if (x<4 || x>15)
            printf("\nOpcion no valida. Ingresa la dimension (4-15): ");
    } while (x<4 || x>15);
    system("cls");
    char tablero[DIM][DIM];
    printf("\n ELIJA JUGADOR\n\n\n");
    printf("\n\n  1) JUGADOR 1 (X)\n");
    printf("\n\n  2) JUGADOR 2 (O)\n");
    elegir:
    scanf("%d",&jugador);
    system("cls");
    if ((jugador!=1) && (jugador!=2))
    {
        printf("\nError: Los jugadores posibles son 1 y 2 ");
        goto elegir;
    }
    do
    {
        inicializar_tablero(tablero,x);
        while ((resto<=(x*x)) && (victoria!=1))
        {
            if (jugador==1)
            {
                jugador++;
               juegan_X_(tablero,x,n);
               for (i=1;i<=x;i++)
           {
    for (j=1;j<=x;j++)
{
if ((tablero[i][j]=='X') && ((tablero[i][j+1])=='X') && ((tablero[i][j+2])=='X') && ((tablero[i][j+3])=='X'))
{
victoria = 1;
}
else if ((tablero[i][j]=='X') && ((tablero[i+1][j])=='X') && ((tablero[i+2][j])=='X') && ((tablero[i+3][j])=='X'))
{
victoria = 1;
}
else if ((tablero[i][j]=='X') && ((tablero[i+1][j-1])=='X') && ((tablero[i+2][j-2])=='X') && ((tablero[i+3][j-3])=='X'))
{
victoria = 1;
}
else if ((tablero[i][j]=='X') && ((tablero[i+1][j+1])=='X') && ((tablero[i+2][j+2])=='X') && ((tablero[i+3][j+3])=='X'))
{
victoria = 1;
}
}
   }
               if (victoria == 1)
               {
                printf("\nJUGADOR 1 GANA!!!\n");
               }
               else
               {
                resto++;
               }
            }
            else if (jugador == 2)
            {
                jugador--;
juegan_O_(tablero,x,n);
for (i=1;i<=x;i++)
           {
    for (j=1;j<=x;j++)
{
if ((tablero[i][j]=='O') && ((tablero[i][j+1])=='O') && ((tablero[i][j+2])=='O') && ((tablero[i][j+3])=='O'))
{
victoria = 1;
}
else if ((tablero[i][j]=='O') && ((tablero[i+1][j])=='O') && ((tablero[i+2][j])=='O') && ((tablero[i+3][j])=='O'))
{
victoria = 1;
}
else if ((tablero[i][j]=='O') && ((tablero[i+1][j-1])=='O') && ((tablero[i+2][j-2])=='O') && ((tablero[i+3][j-3])=='O'))
{
victoria = 1;
}
else if ((tablero[i][j]=='O') && ((tablero[i+1][j+1])=='O') && ((tablero[i+2][j+2])=='O') && ((tablero[i+3][j+3])=='O'))
{
victoria = 1;
}
}
   }
               if (victoria == 1)
               {
                printf("\nJUGADOR 2 GANA!!!\n");
               }
               else
               {   
                  resto++;
               }
            }
        if (resto > (x*x) && (victoria!=1))
        {
          printf("\n\nEMPATE\n\n");
            }
        }
    }while ((resto<=(x*x)) && (victoria!=1));
    resto = 1;
    victoria = 0;
    printf("\nPara jugar nuevamente presione 1: ");
    scanf("%d",&partida);
    system("cls");
    if (partida == 1)
    {
    goto volver;
    }
    system("PAUSE");
}
int inicializar_tablero(char tablero[DIM][DIM],int x)
{
int i,j;
for (i=1; i<=x; i++)
{
for (j=1;j<=x; j++)
{
printf("%c ",tablero[i][j]='.');
}
printf("\n");
}

}
int juegan_X_(char tablero[DIM][DIM],int x,int n)
{
int i,j,k;
do
    {
        printf("\nJuega JUGADOR 1: ");
                    scanf ("%d",&n);
        if (n<1 || n>x)
        {
            printf("Error: las columnas posibles son de 1 a %d",x);
        }   
else if (tablero[1][n]!='.')
{
printf("\nError: la columna ya esta llena.\n ");
      }
    }while((n<1 || n>x) || (tablero[1][n]!='.'));
for (k=x;k>=1;k--)
    {
            if (tablero[k][n]!='.')
                continue;
            else
            {
                tablero[k][n]='X';
                break;
            }
    }
       system("cls"); 
   printf("\nUltima jugada X: Columna %d\n",n);     
    printf("\n");
    for (i=1;i<=x;i++)
    {
        for (j=1;j<=x;j++)
        {
            printf ("%c ",tablero[i][j]);
           
        }
        printf("\n");
    }
}
int juegan_O_(char tablero[DIM][DIM],int x,int n)
{
int i,j,k;
do
    {
        printf("\nJuega JUGADOR 2: ");
                    scanf ("%d",&n);
        if (n<1 || n>x)
        {
            printf("Error: las columnas posibles son de 1 a %d",x);
        }   
else if (tablero[1][n]!='.')
{
printf("\nError: la columna ya esta llena.\n ");
      }
    }while((n<1 || n>x) || (tablero[1][n]!='.'));
for (k=x;k>=1;k--)
    {
            if (tablero[k][n]!='.')
                continue;
            else
            {
                tablero[k][n]='O';
                break;
            }
    }
       system("cls");     
   printf("\nUltima jugada O: Columna %d\n",n);   
    printf("\n");
    for (i=1;i<=x;i++)
    {
        for (j=1;j<=x;j++)
        {
            printf ("%c ",tablero[i][j]);
           
        }
        printf("\n");
    }
}

leosansan

#24
Cita de: KaL3o en  7 Junio 2013, 22:52 PM
hay varios apartes que se repiten, seria bueno utilizar funciones, reducirias varias lineas de codigo

salu2 :)

Pues la verdad que tienes razón y como simple ejercicio voy a rehacer el código usando funciones, o sea modular, para que no se repitan líneas de código más allá de las imprescindibles.

Y ahora que mathias_vg a publicado su código, posteo el mío. Y como una imagen vale más que mil palabras ahí va:


   

Observar que he tenido en cuenta el "detallito" de que si el usuario introduce por error una letra en lugar de un número no entre en un bucle.  ;)

Conste que hay una dimensión de la matriz por usar, todo a su momento, como el tema del color. ¿Te animas a una partidita?:


Código (cpp) [Seleccionar]

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


/**************  FUNCIONES  **************/
char** asig_memoria( int dim_plus);
void tamanyo_consola (char **matriz,int dim_plus);
void jugada(char **matriz,int dim_plus,int jugador, int color_juego);
void imprimir(char **matriz,int dim_plus,int color_juego);
void comprobar_ganador (char **matriz , int jugador, int x, int y, int dim_plus, int color_jueg);
void ganador (char** matriz,int jugador, int dim_plus, int color_juego,int gana_empata);
void contador(int* cont,char** matriz,int jugador, int dim_plus, int color_juego);
void liberar_mem_matriz( char** matriz, int dim_plus);
void salir( char** matriz, int dim_plus);

/**************  FUNCION MAIN   **************/

int main()
{
   setlocale(LC_ALL, "Spanish");
   int color_juego=0,dim_plus=0;
   char d,**matriz;
   int i=0,j=0,dim=0,movimientos=0,k=0,jugador=1,gana_empata=0;
   printf("\n\n\tIngresa la dimensión del tablero de juego (4-10):");
   fflush (stdout);
   do
   {
       scanf ("%d",&dim);
       if (dim<4 || dim>10 )
       {
           printf("\n\n\t\tOpción no valida.\n\n\t\tIngresa la dimensión (4-10): ");
           fflush (stdout);
       }

       while (getchar()!='\n');
   }while (dim<4 || dim>10);
   dim_plus=dim+1;
   matriz = asig_memoria( dim_plus );
   for (i=1;i<dim_plus;i++)
       for (j=1;j<dim_plus;j++)
           matriz[i][j]=' ';
   tamanyo_consola (matriz, dim_plus);
   imprimir( matriz, dim_plus, color_juego);
   while (movimientos<=(dim*dim))
   {
       jugada( matriz, dim, jugador, color_juego);
       imprimir( matriz, dim_plus, color_juego);
       if (jugador==1)
           jugador=2;
       else
           jugador=1;
       movimientos++;
       if (movimientos==dim*dim)
           ganador (matriz,jugador,dim_plus,  color_juego,gana_empata);
   }
   system("PAUSE");
   return 0;
}
/**************  FUNCION JUGADA  **************/
void jugada(char **matriz,int dim_plus,int jugador,int color_juego)
{
   int x=0,y=0,flag=0;
   char simbolo[]={'X','O'};
   do
   {
       do
       {
           flag=0;
           printf("\nJUGADOR %d (%c): ",jugador,simbolo[jugador-1]);
           fflush (stdout);
           scanf ("%d",&y);
           while (getchar()!='\n');
           if (y<1 || y>dim_plus)
               puts("Opción no valida.\nIngresa (4-10)");
       }while(y<1 || y>dim_plus);
       for (x=dim_plus;x>=0;x--)/*<==este for es mejorable*/
       {
           if (matriz[x][y]!=' ' && x!=0)
               continue;
           else if (x==0)
           {
               puts("¡Ya se llego al limite!.\nIntroduzca otro valor.");
               flag=1;
           }
           else
           {
               matriz[x][y]=simbolo[jugador-1];
               break;
           }
       }
   }while (flag==1);
   comprobar_ganador (matriz,jugador,x, y,dim_plus, color_juego);
}
/**************  FUNCION TAMAÑO DE LA CONSOLA  **************/
void tamanyo_consola (char **matriz,int dim_plus)
{
   char tamanyo_consola2[80];
   int tam_x=0,tam_y=0;
   tam_x=3.8*dim_plus; /* con estos valores puedes*/
   tam_y=2*dim_plus ;/*cambiar el tamaño de la consola*/
   sprintf(tamanyo_consola2, "MODE %d,%d", tam_x, tam_y);
   system(tamanyo_consola2);
   system ("cls");
}
/**************  FUNCION ASIGNACION DE MEMORIA  **************/
char **asig_memoria(int dim_plus )
{
   int i;
   char** matriz;
   matriz = malloc( dim_plus * sizeof *matriz );
   for( i = 0; i < dim_plus; ++i )
        matriz[i] = malloc( dim_plus * sizeof **matriz );
  return matriz;
}
/**************  FUNCION IMPRIMIR  **************/
void imprimir(char **matriz,int dim_plus,int color_juego)
{
   int i=0,j=0;
   system ("cls");
   for (i=0;i<dim_plus;i++)
   {
       for (j=1;j<dim_plus;j++)
       {
           if (i==0)
               {
                   printf ("[%d] ",j);
                   fflush (stdout);
               }

           else
               {
                   printf ("(%c) ",matriz[i][j]);
                   fflush (stdout);
               }
       }
       puts("");
   }
}
/**************  FUNCION COMPROBAR GANADOR  **************/
void comprobar_ganador (char **matriz , int jugador, int x, int y,int dim_plus,int color_juego)
{
   int k=1,cont=1;
   for (k=1;k<5;k++)
   {
       if ( x+k <= dim_plus && y+k <= dim_plus && matriz[x][y]==matriz[x+k][y+k])
           contador (&cont, matriz,jugador,dim_plus,  color_juego);
       else
           break;
   }
   for (k=1;k<5;k++)
   {
       if ( x+k > 0 && y+k > 0 && matriz[x][y]==matriz[x-k][y-k])
           contador (&cont, matriz,jugador,dim_plus,  color_juego);
       else
           break;
   }
   cont=1;
   for (k=1;k<5;k++)
   {
       if ( x+k <= dim_plus && y+k > 0 && matriz[x][y]==matriz[x+k][y-k])
           contador (&cont, matriz,jugador,dim_plus,  color_juego);
       else
           break;
   }
   for (k=1;k<5;k++)
   {
       if ( x+k > 0 && y+k <= dim_plus && matriz[x][y]==matriz[x-k][y+k])
           contador (&cont, matriz,jugador,dim_plus,  color_juego);
       else
           break;
   }
   cont=1;
   for (k=1;k<5;k++)
   {
       if ( x+k <= dim_plus && matriz[x][y]==matriz[x+k][y])
           contador (&cont, matriz,jugador,dim_plus,  color_juego);
       else
           break;
   }
    cont=1;
    for (k=1;k<5;k++)
   {
       if ( y+k <= dim_plus && matriz[x][y]==matriz[x][y+k])
           contador (&cont, matriz,jugador,dim_plus,  color_juego);
       else
           break;
   }
   for (k=1;k<5;k++)
   {
       if (y+k > 0 && matriz[x][y]==matriz[x][y-k] )
           contador (&cont, matriz,jugador,dim_plus,  color_juego);
       else
           break;
   }
}
/**************  FUNCION LIBERAR MEMORIA  **************/
void liberar_mem_matriz( char** matriz, int dim_plus )
{
  int i;
  for( i = 0; i < dim_plus; ++i )
     free( matriz[i] );
  free( matriz );
}
/**************  FUNCION CONTADOR   **************/
void contador(int* cont,char** matriz,int jugador, int dim_plus, int color_juego)
{
   int gana_empata=1;
   *cont=+*cont+1;
   if (*cont==4)
   {
       imprimir( matriz, dim_plus+1, color_juego);
       ganador (matriz,jugador,dim_plus,  color_juego,gana_empata);
   }
}
/**************  FUNCION GANADOR   **************/
void ganador (char** matriz,int jugador, int dim_plus, int color_juego,int gana_empata)
{
   if (gana_empata==1)
       printf ("Ganó el JUGADOR %d\n",jugador);
   else if (gana_empata==0)
       puts("EMPATE");
   else
       puts("¡ERROR!");
   puts ("Hasta lueguito.");
   salir( matriz, dim_plus );
}
/**************  FUNCION SALIR  **************/
void salir( char** matriz, int dim_plus )
{
   int i;
   for( i = 0; i < dim_plus; ++i )
       free( matriz[i] );
   free( matriz );
   system ("pause");
   exit (0);
}
/**************  FIN  **************/


Próximamente habrán más novedades/variantes del /los juegos, tanto del Conecta-4 como del 4 en línea.

Por supuesto que serán bienvenidas las críticasy/o sugerencias.

Ya adelanto que la intención es que tenga color y que se pueda elegir entre seguir jugando o salir. Detallitos que espero hagan más sugerente el/los jueguitos.

Y sí, ya sé que lo he "complicado" con tanta función pero de eso iba el "envite" deKaL3o . ;)


Saluditos!.

mathias_vg

Me podrian decir porque entra en bucle cuando elijo un caracter? Que es lo que tengo que modificar?

Muchas gracias

leosansan

#26
Cita de: mathias_vg en 11 Junio 2013, 19:57 PM
Me podrían decir porque entra en bucle cuando elijo un caracter? Que es lo que tengo que modificar?


Ya sabía que tarde o temprano te darías cuanta por ti mismo. Se debe a que el caracter, no utilizado porque el scanf no lo reconoce, ya que el espera un int, se queda en el bufer y en la próxima llamada al scanf éste toma automáticamente el valor del carcater que quedo en el bufer  y y así sucesivamente  entrando por ello en un bucle.

Fíjate e los detalles de mi código:

Código (cpp) [Seleccionar]
do
   {
       scanf ("%d",&dim);
       if (dim<4 || dim>10 )
       {
           printf("\n\n\t\tOpción no valida.\n\n\t\tIngresa la dimensión (4-10): ");
           fflush (stdout);
       }

       while (getchar()!='\n'); /*<==limpio el buffer e impido entrar en un bucle*/
   }while (dim<4 || dim>10);


Eso en los scanf de tipos numéricos, no hace falta cuando son de tipo char.


Saluditos! .... ..

mathias_vg

Gracias leosansan, ahora, te pregunto, hay alguna manera de hacerlo sin tener que utilizar la funcion getchar? ya que no la dimos en clase y no se si la puedo utilizar.
algo como transformar el caracter de entrada en numero y asi que me marque el error?

Saludos

leosansan

Cita de: mathias_vg en 12 Junio 2013, 15:05 PM
Gracias leosansan, ahora, te pregunto, hay alguna manera de hacerlo sin tener que utilizar la funcion getchar? ya que no la dimos en clase y no se si la puedo utilizar.
algo como transformar el caracter de entrada en numero y así que me marque el error?


Si sólo fuera un caracter podrías hacer uso de atoi, y aún así habría que añadir la condición de >0 y <15, pero como ves el "15" no es un caracter sino una cadena, con lo que no valdría el uso de dicha función y, en principio lo que se me ocurre a bote proto, sería  usar una función como "strol". Pero se me hace difícil entender que no uses getchar, que es una función muy usada de la librería stdio y, a cambio, te metas con funciones de la librería string que conllevan más cosas para lograr el objetivo.

Usa getchar.

Es más, en varios compiladores -e.j. Dev-C++- es una función que se aprende al tiempo que el uso de main o printf, pues si no la ponen al final del código el programa se ejecuta y se cierra de un golpe y, en ese caso, se usa getchar "como freno" para "ver" la consola antes de que ésta se cierre.



Saluditos!.