funcion para hundir la flota enemiga

Iniciado por carlosm, 4 Junio 2019, 01:35 AM

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

carlosm

Hola!
En el siguiente juego de Hundir la flota me han pedido realizar una función que realice un ataque aéreo especial que haga explotar varias posiciones del tablero enemigo al azar. Esta función puede ser invocada solo una vez durante todo el juego con un truco, por ejemplo introduciendo la fila "Z" y la columna 99..
Ayuda porfa

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <conio.h>
#include <string.h>


/*definimos las filas y columnas*/

#define NF 10
#define NC 10


/*definimos las variables a usar en cada una de las funciones*/


int transformanumero(char num);
int transformaletra(char letra);
void iniciartablero(int m[NF][NC]);
int gameover(int m[NF][NC], int cont);
void colocar(int m[NF][NC]);
void imprimetablero(int m[NF][NC]);
void turnoJugador(int m[NF][NC], int m2[NF][NC]);

void portaaviones(int m[NF][NC]);
void acorazado(int m[NF][NC]);
void submarino(int m[NF][NC]);
void patrullero(int m[NF][NC]);
void soldado(int m[NF][NC]);

/*Se definen las variables a usar, junto con la matriz  */

main()
{
    int findeljuego = 0, cont1 = 0, cont2 = 0;

    int jugador1[NF][NC], jugador2 [NF][NC];

    iniciartablero(jugador1);
    iniciartablero(jugador2);

    printf("Jugador 1, coloca tus barcos:\n");
    colocar(jugador1);


    printf("Jugador 2, coloca tus barcos:\n");
    colocar(jugador2);

/*Se leen los turnos de los jugadores y se indica si a ganado o  ha perdido para ambos jugadores
    Se usara dos colores para distinguir si ha ganado con el ataque o se aha esquivado con el ataque
   Despues de terminar con las posiciones del oponwete se saldrá del juego */
   
   
    while(findeljuego == 0){

        if(gameover(jugador1, cont1) == 0){

            system("cls");
            printf("Turno, Jugador 1:\n");
            imprimetablero(jugador1);
            turnoJugador(jugador2, jugador1);

            if(gameover(jugador2, cont2)){
                findeljuego = 1;
                system("cls");
                imprimetablero(jugador1);
                system("COLOR 02");
                printf("\n");
                printf("\nHa ganado Jugador 1\n");
            }
        }

        if(gameover(jugador2, cont2) == 0){
            system("cls");
            printf("Turno, Jugador 2:\n");
            imprimetablero(jugador2);
            turnoJugador(jugador1, jugador2);

            if(gameover(jugador1, cont1)){
                findeljuego = 1;
                system("cls");
                imprimetablero(jugador2);
                system("COLOR 02");
                printf("\n");
                printf("\nHa ganado Jugador 2\n");
            }
        }
    }
}

/*********************************************************/

/* Esta funcion va a transformar letras a numeros */
int transformaletra(char letra)
{
    int coordenada;

    if(letra >= 'A' || letra < 'Z'){
        coordenada = letra - 65;
    }

    return(coordenada);
}

int transformanumero(char num)
{
    int coordenada;

    if(num >= '0' || num < '9'){
        coordenada = num - 48;
    }

    return(coordenada);
}

/* Esta funcion va iniciar el tablero desde la posicion 0 */
void iniciartablero(int m[NF][NC]){

   for(int i = 0; i < NF; i++){
        for (int j = 0; j < NC; j++){
            m[j]= 0;
      }
   }
}

/* Esta funcion va a detectar el fin del juego */

int gameover(int m[NF][NC], int cont2){

    int res = 0, cont1 = 0;

    for(int i = 0; i < NF; i++){
        for (int j = 0; j < NC; j++){
           if(m[j] == 2){
               cont1 += 1;
           }
          
           if(m[j] == 2 || m[j] == 1){
              cont2++;
         }
       }
   }

   if(cont1 == cont2){
        res = 1;
   }

   return (res);
}
/* Esta funcion va a realizar la colocacion de cada barco en las posiciones pedidas */
void colocar(int m[NF][NC]){

    int fila, columna2;
    char columna;

    imprimetablero(m);
    portaaviones(m);
    acorazado(m);
    submarino(m);
    patrullero(m);
    soldado(m);


    system("cls");
}

/*Esta funcion va a mostrar el tablero de ambos jugadores */

void imprimetablero(int m[NF][NC]){

    for(int i = 0; i <= NF; i++){
        if(i == 0){
            printf("  ");
        } else{
            printf("%c ", 'A'+i-1);
        }
    }

    printf("\n");

    for(int i=0; i<NF; i++){
        printf("%d ", i);

        for (int j=0; j<NC; j++){

            if(m[j] == 1){
                printf("# ");
            }else if(m[j] == 2){
               printf("X ");
         }else{
                printf("~ ");
            }
        }
        printf("\n");
    }
}

/*Esta funcion va a hundir la flota del oponete a través de turnos */
void turnoJugador(int m[NF][NC], int m2[NF][NC]){
    char letra, fila;
    int filas, columna;

        do{
         do{
               
              printf("Introduce una fila: ");
              fflush(stdin);
              scanf("%c", &fila);
              fflush(stdin);          
              filas = transformanumero(fila);
             
           }while(filas < 0 || filas > 10);
      }while(!isdigit(fila));

        do{
           do{
               printf("Introduce una columna: ");
               fflush(stdin);
               scanf("%c", &letra);
               fflush(stdin);
               letra  = toupper(letra);
               columna = transformaletra(letra);
            }while(columna >= NC || columna < 0);
        }while(isdigit(letra));

        columna = transformaletra(letra);

    if(m[filas][columna] > 0 && m[fila][columna] != 2){
        printf("\nBarco Hundido\n");
        m[filas][columna] = 2;
        system("COLOR 4f");

        if(m2[filas][columna] != 1){
            m2[filas][columna] = 2;
        }
        printf("\nPulsa enter para acabar el turno");
        getch();
        system("COLOR 07");

    }else{

        system("COLOR 30");
        printf("\nAgua\n");
        printf("\nPulsa enter para acabar el turno");
        getch();
        system("COLOR 07");
    }
}

/*Todas estas funciones auxiliares dibujan los barcos que se usaran */


/******************************Barcos y soldado*****************************************************/

void portaaviones(int m[NF][NC]){

    char pos, letra, fila;
    int filas, columna;

    printf("Como quieres colocar el porta aviones *****\n");
    do{
        printf("Horizonal (H), Vertical(V): ");
        scanf("%s", &pos);
    }while(toupper(pos) != 'H' && toupper(pos) != 'V' );

    switch(toupper(pos)){
       
    case 'H':
       
        do{
         do{
               
              printf("Introduce una fila: ");
              fflush(stdin);
              scanf("%c", &fila);
              fflush(stdin);          
              filas = transformanumero(fila);
             
           }while(filas < 0 || filas > 10);
      }while(!isdigit(fila));

       system("cls");

        printf("elige 5 columnas para ubicarlo: \n");
        for(int i = 0; i < 5; i++){
           
         do{
             do{
                 printf("Introduce una columna %d: ", i+1);
                 fflush(stdin);
                 scanf("%c", &letra);
                 fflush(stdin);
                 letra  = toupper(letra);
                    
                 columna = transformaletra(letra);
                    
                 if(m[filas][columna] == 1){
                     printf("\nYa has colocado el barco en la posicion [%d][%c]\n", filas, letra);
                     i--;
               }
                  
             }while(isdigit(letra));
         }while ((columna >= NC) || (columna < 0));


           m[filas][columna] = 1;
        }


        imprimetablero(m);
        getch();
        system("cls");

        break;

    case 'V':

        do{
           do{
              
               printf("En que columna lo quieres colocar: ");
               fflush(stdin);
               scanf("%c", &letra);
               fflush(stdin);
               letra = toupper(letra);
              
               columna = transformaletra(letra);
           
         }while(isdigit(letra));
      }while ((columna >= NC) || (columna < 0));

        system("cls");

        printf("elige 5 filas para ubicarlo: \n");
        for(int i = 0; i < 5; i++){
           
            do{
               do{
                 printf("Introduce una fila %: ", i+1);
                 fflush(stdin);
                 scanf("%c", &fila);
                 fflush(stdin);          
                 filas = transformanumero(fila);
              }while(!isdigit(fila));
              
               if(m[filas][columna] == 1){
                  printf("\nYa has colocado el barco en la posicion [%d][%c]\n", filas, letra);
                  i--;
            }            
            
            }while((filas < 0 && filas > 10) || !isdigit(fila));

            m[filas][columna] = 1;
        }

        imprimetablero(m);
        getch();
        system("cls");

        break;
    }
}

void acorazado(int m[NF][NC]){

    char pos, letra, fila;
    int filas, columna;

    printf("Como quieres colocar el acorazado ****\n");
    do{
        printf("Horizonal (H), Vertical(V): ");
        scanf("%s", &pos);
    }while(toupper(pos) != 'H' && toupper(pos) != 'V' );

    switch(toupper(pos)){
       
    case 'H':
       
        do{
         do{
               
              printf("En que fila lo quieres colocar: ");
              fflush(stdin);
              scanf("%c", &fila);
              fflush(stdin);          
              filas = transformanumero(fila);
             
           }while(filas < 0 || filas > 10);
      }while(!isdigit(fila));

       system("cls");

        printf("elige 4 columnas para ubicarlo: \n");
        for(int i = 0; i < 4; i++){
           
           do{
               printf("Introduce una columna: ");
               fflush(stdin);
               scanf("%c", &letra);
               fflush(stdin);
               letra  = toupper(letra);
              
               columna = transformaletra(letra);
              
               if(m[filas][columna] == 1){
                  printf("\nYa has colocado el barco en la posicion [%d][%c]\n", filas, letra);
                  i--;
            }
            
           }while((isdigit(letra) || columna >= NC || columna < 0));


           m[filas][columna] = 1;
        }


        imprimetablero(m);
        getch();
        system("cls");

        break;

    case 'V':

        do{
           do{
              
               printf("En que columna lo quieres colocar: ");
               fflush(stdin);
               scanf("%c", &letra);
               fflush(stdin);
               letra = toupper(letra);
              
               columna = transformaletra(letra);
           
         }while(isdigit(letra));
      }while ((columna >= NC) || (columna < 0));

        system("cls");

        printf("elige 4 filas para ubicarlo: \n");
        for(int i = 0; i < 4; i++){
           
            do{
               
               do{
                 printf("Introduce una fila %d: ", i+1);
                 fflush(stdin);
                 scanf("%c", &fila);
                 fflush(stdin);          
                 filas = transformanumero(fila);
              }while(!isdigit(fila));
              
               if(m[filas][columna] == 1){
                  printf("\nYa has colocado el barco en la posicion [%d][%c]\n", filas, letra);
                  i--;
            }            
            
            }while(filas < 0 && filas > 10);

            m[filas][columna] = 1;
        }

        imprimetablero(m);
        getch();
        system("cls");

        break;
    }

}

void submarino(int m[NF][NC]){

    char pos, letra, fila;
    int filas, columna;

    printf("Como quieres colocar el submarino ***\n");
    do{
        printf("Horizonal (H), Vertical(V): ");
        scanf("%s", &pos);
    }while(toupper(pos) != 'H' && toupper(pos) != 'V' );

    switch(toupper(pos)){
       
    case 'H':
       
        do{
         do{
               
              printf("En que fila lo quieres colocar: ");
              fflush(stdin);
              scanf("%c", &fila);
              fflush(stdin);          
              filas = transformanumero(fila);
             
           }while(filas < 0 || filas > 10);
      }while(!isdigit(fila));

       system("cls");

        printf("elige 3 columnas para ubicarlo: \n");
        for(int i = 0; i < 3; i++){
           
           do{
               printf("Introduce una columna: ");
               fflush(stdin);
               scanf("%c", &letra);
               fflush(stdin);
               letra  = toupper(letra);
              
               columna = transformaletra(letra);
              
               if(m[filas][columna] == 1){
                  printf("\nYa has colocado el barco en la posicion [%d][%c]\n", filas, letra);
                  i--;
            }
            
           }while(isdigit(letra) || columna >= NC || columna < 0);


           m[filas][columna] = 1;
        }


        imprimetablero(m);
        getch();
        system("cls");

        break;

    case 'V':

        do{
           do{
              
               printf("En que columna lo quieres colocar: ");
               fflush(stdin);
               scanf("%c", &letra);
               fflush(stdin);
               letra = toupper(letra);
              
               columna = transformaletra(letra);
           
         }while(isdigit(letra));
      }while ((columna >= NC) || (columna < 0));

        system("cls");

        printf("elige 3 filas para ubicarlo: \n");
       
        for(int i = 0; i < 3; i++){

           
            do{
               
               do{
                 printf("Introduce una fila %d: ", i+1);
                 fflush(stdin);
                 scanf("%c", &fila);
                 fflush(stdin);          
                 filas = transformanumero(fila);
              }while(!isdigit(fila));
              
               if(m[filas][columna] == 1){
                  printf("\nYa has colocado el barco en la posicion [%d][%c]\n", filas, letra);
                  i--;
            }            
            
            }while(filas < 0 && filas > 10);

            m[filas][columna] = 1;
        }

        imprimetablero(m);
        getch();
        system("cls");

        break;
    }
}

void patrullero(int m[NF][NC]){

    char pos, letra, fila;
    int filas, columna;

    printf("Como quieres colocar al patrullero **\n");
    do{
        printf("Horizonal (H), Vertical(V): ");
        scanf("%s", &pos);
    }while(toupper(pos) != 'H' && toupper(pos) != 'V' );

    switch(toupper(pos)){
       
    case 'H':
       
        do{
         do{
               
              printf("En que fila lo quieres colocar: ");
              fflush(stdin);
              scanf("%c", &fila);
              fflush(stdin);          
              filas = transformanumero(fila);
             
           }while(filas < 0 || filas > 10);
      }while(!isdigit(fila));

       system("cls");

        printf("elige 2 columnas para ubicarlo: \n");
        for(int i = 0; i < 2; i++){
           
           do{
               printf("Introduce una columna: ");
               fflush(stdin);
               scanf("%c", &letra);
               fflush(stdin);
               letra  = toupper(letra);
              
               columna = transformaletra(letra);
              
               if(m[filas][columna] == 1){
                  printf("\nYa has colocado el barco en la posicion [%d][%c]\n", filas, letra);
                  i--;
            }
            
           }while(isdigit(letra) || columna >= NC || columna < 0);


           m[filas][columna] = 1;
        }


        imprimetablero(m);
        getch();
        system("cls");

        break;

    case 'V':

        do{
           do{
              
               printf("En que columna lo quieres colocar: ");
               fflush(stdin);
               scanf("%c", &letra);
               fflush(stdin);
               letra = toupper(letra);
              
               columna = transformaletra(letra);
           
         }while(isdigit(letra));
      }while ((columna >= NC) || (columna < 0));

        system("cls");

        printf("elige 2 filas para ubicarlo: \n");
        for(int i = 0; i < 2; i++){
           
            do{
               
               do{
                 printf("Introduce una fila %d: ", i+1);
                 fflush(stdin);
                 scanf("%c", &fila);
                 fflush(stdin);          
                 filas = transformanumero(fila);
              }while(!isdigit(fila));
              
               if(m[filas][columna] == 1){
                  printf("\nYa has colocado el barco en la posicion [%d][%c]\n", filas, letra);
                  i--;
            }            
            
            }while(filas < 0 && filas > 10);

            m[filas][columna] = 1;
        }

        imprimetablero(m);
        getch();
        system("cls");

        break;
    }
}

void soldado(int m[NF][NC]){

    char pos, letra, fila;
    int filas, columna, flag;

   do{
      flag = 0;
      
      printf("Como quieres colocar donde quieres colocar al soldado *\n");
      
        do{
           do{
              
               printf("En que columna lo quieres colocar: ");
               fflush(stdin);
               scanf("%c", &letra);
               fflush(stdin);
               letra = toupper(letra);
              
               columna = transformaletra(letra);
           
         }while(isdigit(letra));
      }while ((columna >= NC) || (columna < 0));
   
        do{
         do{
               
              printf("En que fila lo quieres colocar: ");
              fflush(stdin);
              scanf("%c", &fila);
              fflush(stdin);          
              filas = transformanumero(fila);
             
           }while(filas < 0 || filas > 10);
      }while(!isdigit(fila));
      
       if(m[filas][columna] == 1){
           printf("\nNo puedes colocar al soldado sobre un barco en la posicion [%d][%c]\n", filas, letra);
           flag = 1;
      }
      
   }while(flag != 0);


    m[filas][columna] = 1;

    imprimetablero(m);
    getch();
    system("cls");
}

@XSStringManolo

#1
Lo has creado tu? Me parece muchísimo código para un juego con mecánicas tan sencillas. Pero si funciona dpm.

Para la funcion que preguntas yo lo haría de la siguiente forma:
Declarar variable static y darle valor 0;
Dentro de la funcion la primera instruccion es sumarle a la variable +1 para que deje de valer 0;

En la llamada a la funcion desde main, en el bucle del juego, esta la metes dentro de un if:
if (condicionDeLlamada igual a true y variableStatic igual a cero)
{
funcion();
}

Bastante sencillo y pocas lineas.

Ahora, para el contenido de la funcion, simplemente usa la funcion rand();
Puedes modificar los parametros y hacer operaciones con el resultado de rand() para que te de un numero de una casilla.

Ponle de semilla a la funcion, la hora local del sistema. La funcion es srand() que viene de seedrandom es decir "semilla aleatoria". Esto es para que el programa utilice un numero para generarte otro pseudoaleatorio. Al meterle la hora local siempre va a tener un valor distinto. Ya que la hora locak cambia cada rato.

Cuando se cumpla la condicion para llamar a esta funcion simplemente ponle a una variable global a la que le asignaste false en la declaración, el valor true al complirse la condicion.
Despues con un AND en el if dices que si la variable es true y la variable static es igual a 0 se realice la llamada a la funcion.
Despues dentro de la funcion le sumas 1 para que nunca se vuelvan a cumplir las 2 condiciones. Por lo que nunca se volvera a llamar a la funcion. Solo esa primera vez que la variable static contador valia 0.


PD: No se si tienes más dudas, no entiendo los codigos sin mirarlos miy detenidamente. Asique no puedo decirte nada del programa sin ejecutarlo y estoy desde el movil. A cerca de dudas, problemas y trozos de codigo si puedo ayudarte. Pero con todo el programa a la vez sin pararme a buscar para que se usa cada variable, cada funcion etc no.

Por eso mismo yo pongo nombres exageradamente largos de todos los codigos que hago en plan:
p_haciaTerceraLetraDeStringMiNombre;

si no es un coñazo mirar todo el programa y buscar el puntero en 50 sitios para encontrarlo dentro de un for y tener que mirar todo el funcionamiento para sacar algo sencillo.

A parte puedes usar los codigos geshi en el foro para meter el codigo dentro y que se vea el codigo en colores como en el ide.

Dale a editar mensaje y ponlo, así será más agradable de leer.

carlosm

Hola!
No, fue un trabajo en grupo solo aporte cosas muy simples por el hecho de que soy nuevo en esto y estoy tratando de entender, aun que se me dificulta mucho...
muchas gracias por tu aporte...

Para ser sincero no entiendo muy bien lo que me quieres decir, podrías ayudarme a cambiarlo en esa parte porfavor...
disculpa si te molesto....

@XSStringManolo

#3
No molestas, de eso van los foros, de hacer preguntas y responderlas.

Siento no haber sido claro. Lo intentaré de nuevo.

La funcion que quieres crear, dices que solo quieres que se ejecute una vez. Para eso declaramos una variable global static:

static int vecesQueSeEjecutoLaFuncionAtaqueAereoEspecial = 0;


Tambien vamos a usar una variable booleana para saber si se ha cumplido la condicion que queremos que se cumpla para realizar el ataque aereo especial.

bool llamarALaFuncionAtaqueAereoEspecial = false;


Ahora necesitamos la condicion para llamar a la funcion AtaqueAereoEspecial.

if (fila[y] == 'Z' && columna[y] == 99)
{
llamarALaFuncionAtaqueAereoEspecial = true;
}

Dentro del bucle del juego haremos la llamada a la funcion, si nunca antes se ha llamado, y si la condicion se cumple:

if (vecesQueSeEjecutoLaFuncionAtaqueAereoEspecial ==0 && llamarALaFuncionAtaqueAereoEspecial == true)
{
AtaqueAereoEspecial();
}

Por ultimo creamos la funcion:

void AtaqueAereoEspecial()
{
vecesQueSeEjecutoLaFuncionAtaqueAereoEspecial++;

/*Aqui le metes la hora local usando la biblioteca time y srand();

Aqui generas el numero aleatorio con rand(); y elijes entre que valores quieres que esté el numero generado. Si tienes 10 columnas y 10 filas, le indicas que te de un numero entre 1 y 10 para las columnas.

Aqui vuelves a llamar a rand(); para generar un numero aleatorio entre 1 y 10 para las filas.

Aqui llamas a la funcion que tengas para realizar el ataque en la columna y la fila aleatoria.
}

Aqui tienes ejemplos del uso de rand y srand en C https://www.aprenderaprogramar.com/index.php?option=com_content&view=article&id=917:generar-numeros-o-secuencias-aleatorios-en-c-intervalos-srand-y-rand-time-null-randmax-cu00525f&catid=82&Itemid=210

carlosm

Bueno ahora que ya tengo todo!
podrías corregirme si algo estoy mal ...

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

Esto en la función principal
   static int ataque=0;
   bool ataqueespecial=false;
   
   Aquila la fila y columnas no deberían ser las matrices que utilizamos?
   if (fila == 'Z' && columna[j] == 99)
   {
   ataqueespecial = true;
   }


/*bucle del juego*/
   if (ataque ==0 && ataqueespecial == true)
   {
   ataqueespecial();
   }
Esta sería la función entonces:
   void ataqueespecial(){
   ataque++;

   srand(time(NULL));
   int columnas = rand() %10;
   rand();
   turnoJugador(jugador1, jugador2);
   }

@XSStringManolo

En general las variables que vas a usar no deben ir dentro de la funcion principal en plan:
#include <time.h>
main()
{
static int variable1,
bool variable2;
return
}
Declara las variables encima de main para que sean globales.

A penas mire el código del programa, era un ejemplo de uso para que adecuases al programa no para que hicieses copia y pega jajaja.

Si pones ++ataque; en lugar de ataque++; se ejecuta más rapido.

En:
int columnas = rand() %10;
Creo que así te genera numeros del 0 al 9. Pero no estoy seguro al 100% no recuerdo. Metelo en un bucle con cout para ver todos los numeros que te genera y lo compruebas. Si pasa eso le pones rand() %10+1; Y listo. Así siempre vas sumar 1 tras la operación y todos los mumeros serán entre 1 y 10 ambos incluidos. O te devuelve entre 0 y 10. Miralo y arreglalo. No tiene mucho má

rand(); En esta segunda llamada me referia a que hicieses lo mismo que la llamada a rand de arriba, pero guardar un numero distinto en int filas, en vez de en int columnas.

Puede ser que el numero que te de, sea el mismo que en la llamada anterior porque no dio tiempo a que se cambiase la hora local, en ese caso, o haces una operación sencilla en plan:
int filas = (int columnas +1) /2 //Es solo un ejemplo.

O pausas X tiempo la ejecucion para que cambie la hora //feo feo

O generas el numero para columnas al principio del programa y el de filas aqui.//poco fiable

O cambias el formato de la hora a milisegundos//Funcionara?

O cambias la semilla con srand(semilla); antes de la llamada a rand();
Ya sea srand(1); o a poder ser algo más aleatorio. Si no siempre se te usara la misma serie.

Lo que a ti se te ocurra. Por ejemplo yo suelo multiplicar el numero de time por otro numero ya que el numero de time va a ser distinto en cada ejecucion.

Yo no puedo compilar el programa que tendría que hacer copia y pega desde el movil a un archivo, meterlo en la tarjeta sd, apagar el móvil, meter la tarjeta en el pc, compilar, arreglar si algo no funciona, volver a guardar en tarjeta sd, meter tarjeta en el movil, encenderlo, y pegar el archivo.

Es más sencillo que pruebes el juego, busques los errores jugando, y los comentes aquí. Así según el error que sea sabré en donde buscar el problema sin tener que entender todo el codigo. A parte cuaquiera que lea el post con el error que tienes podría ayudarte.