campo minado -ramdom , etc

maquineta

Membro
linguagem C

então, meu professor pediu um programa de campo minado (classico) nada simples , vi uns por ai na net e esse é bemm mais complicado

--1--
para sortear as bombas pensei algo como isso

será que tem como fazer assim (EXEMPLO)
o cara pede um campo minado 4x5 e 5 bombas

eu pego esses numeros e peço pro rand gerar uma ordem de numeros de 1 a (nL x nC=20) distribuídos de acordo com a semente e coloco num vetor e depois coloco na mesma ordem an matriz sendo q os numeros 1 até o nB(numero de bombas=5) fica igual a 'B' e o resto como sem ser bomba

tem como fazer isto?? como?

---2---
outra maneira nao sei se boa seria sortear algumas colunas e sortear uma posicao e la colocar uma bomba

alguem com + experiencia teria noção do melhor a se fazer?
 
Desculpa, mas não percebi bem qual a tua dúvida.

Queres saber como geras uma posição aleatória ou queres saber como colocas os valores do random?

HecKel
 
eu tenho uma ideia de como randomizar a escolha das bombas de acordo com o numero de bombas
só nao sei como é q faz o codigo pra isso...

queria saber priemiramente se a 1a ideia q eu dei pode ser feita
e segundo como faze-la

ou se tiverem uma ideia melhor eu aceito :)


exemplo temos uma matriz 2x3

x x x
x x x

quero randomizar a escolha de 3 bombas
eu criaria um vetor de 6 espaços (0 a 5)
e pelo random colocaria nele embaralhando os numeros 0 a 5 sendo q de 0 a 2 seriam as bombas
vamos dizer q o random fez 5 2 3 4 1 0
ai cocolaria na matriz os B no 0 a 2

ficaria

X B X
X B B


entendeu? tem como o random embaralhar uma ordem de numeros atraves de um seed?
 
Última edição:
Boas!

Assim de repente..., a forma que me ocorre de não colidires bombas, é confirmares se a posição que o random gerou já contem bomba, se não, ocupas, se sim, voltas a fazer random.

Não estou a ver outra forma de fazer isso, random é isso mesmo, ser aleatório, não consegues garantir 5 posições distintas com um random sem fazeres verificações.

Sobre a forma de apagares um post, carrega em editar e aparece-te uma opção para apagar, se não vires aí, vai ao modo avançado que tem ;)

HecKel
 
pra um jogo do genero o mais indicado\simples é um vector\array bidimensional (linha, coluna). inicializas tudo a vazio

para sorteares a posição é so arranjares um valor aleatorio tanto pra 1 como o outro, entre 0 e o valor max de linha e coluna e vereficares se o mesmo ja existe, se tal não ocorrer, so tens que repetir. prenches a posição. se tiveres que prencher as colunas adjacentes com a distancia a bomba, agora é o melhor momento

para gerares sempre aleatorios basta inicializares a semente a cada criação de bomba, em c++ tens por exemplo srand(time(0));
 
Código:
#include <stdio.h>
#include <stdlib.h>

typedef int TipoChave;

typedef struct {
  int Chave;
  /* outros componentes */
} TipoItem;

typedef struct Celula_str *Apontador;

typedef struct Celula_str {
  TipoItem Item;
  Apontador Prox;
} Celula;

typedef struct {
  Apontador Primeiro, Ultimo;
} TipoLista;


/*
a função sorteia as bombas dada uma matriz de tamanho nL x nC e com nB numero de bombas
*/

char ** sorteiaBombas(int nL, int nC, int nB, int semente)
{
  int a, b, nB2=-1; 
    char ** B = dynchar((nL+4),(nC+4));
      while (nB2<nB)  {
         a = rand() %nL;
         b = rand() %nC;
         /* +1 para o resto ficar entre 1 e nL e +1 pela matriz ser maior pra contar as bombas*/
         /*+2 pelo aumento da matriz para facilitar fechar posicoes*/
         if (B[a+4][b+4]!='B') {
            B[a+4][b+4]='B';
            nB2++;         
                                    }
                      }     
   return B;
}
        
/*função que conta e coloca um caractere de de acordo com  número de bombas adjacentes a o local*/
void contaBombas(int nL, int nC, char **Bombas)
{
     int i,j,k,l;
     for (i = 3; i < nL; i++)
         for (j = 3; j < nC; j++){
            if (Bombas[i][j]!='B') {Bombas[i][j]=='0';}
            if (Bombas[i][j]=='B') {
               for (k=i+1; k < i; k++)
                  for (l=j+1; l < j; l++){
                     if(Bombas[k][l]!='B') {Bombas[k][l]++;}
                                           }
                                    }
                                 }
    
}

/*função para imprimir o campo minado*/
void imprimeCampoMinado (int nL, int nC, char **Campo)
{
   int i, j;
   printf ("  |");
   for (j=3; j<nC ; j++)
      printf (" j");
     
   printf("\n---");
   for (j=3; j<nC ; j++)
      printf (" -");
 
   for (i=3; i<nL ; i++){
       printf ("%d |",i);
      for (j=3; j<nC ; j++){    
                  printf (" %c",Campo[i][j]);
                        }
                           }
}

/*função que abre a posição de acordo com a regra do jogo e a jogada feita*/
int abrePosicao(int nL, int nC, char **Bombas, char **Campo, int lin, int col)
{
    int i, j, N;
   
   
    for (i=0; i<nL+4; i=i+nL+3)
       Bombas[i][j]='1';
   
    for(i=0; i<nC+4; i=i+nC+3)
       Bombas[i][j]='1';
      
      
    if (Bombas[lin+3][col+3]=='B'){
       if (Campo[lin+3][col+3]!='B') {
          Campo[lin+3][col+3]='B';
          N++;
          return 0;
                                     }
                                  }
             
    if (Bombas[lin+3][col+3]>'0' && Bombas[lin+3][col+3]<'8' ) {
       char b = Bombas[lin+3][col+3];
           if (Campo[lin+3][col+3]!=b){
              Campo[lin+3][col+3]=b;
              N++;      
                                        }
                                                               }
                                  
    if (Bombas[lin+3][col+3]=='0') {
       if (Campo[lin+3][col+3]!=' ')  {
          Campo[lin+3][col+3]=' ';
          N++;
                                      }
       /*+1-1=0+2=2 +1+1=2+2=4*/
       for (i=lin+2; i< lin+4 ; i++)
          for (j=col+2; j< col+4 ; j++)
          return abrePosicao(nL, nC, Bombas, Campo, i, j);                                   }    
   
  return N;
}

/*função que fecha as posições, necessária para a volta de jogadas*/
int fechaPosicao(int nL, int nC, char **Campo, int lin, int col)
{
   
    int i, j, g=0,A=0;
   
    if (Campo[lin+3][col+3]!='*'){
    Campo[lin+3][col+3]='*';
    A++;
                                   }
   
    for (i=0; i<nL+4; i=i+nL+3)
       Campo[lin][col]='1';
   
    for(i=0; i<nC+4; i=i+nC+3)
       Campo[lin][col]='1';
      
    for (i=1; i<nL+3; i=i+nL+2)
       Campo[lin][col]=' ';
   
    for(i=1; i<nC+3; i=i+nC+2)
       Campo[lin][col]=' ';
           
    /*+1-1=0+2=2 +1+1=2+2=4*/
       for (i=lin+2; i< lin+4 ; i++)
          for (j=col+2; j< col+4 ; j++)
          if (Campo[i][j]!=' '){g++;}
         
    if (g!=0){
       for (i=lin+2; i< lin+4 ; i++)
          for (j=col+2; j< col+4 ; j++)
             return fechaPosicao(nL, nC, Campo, i, j);
             }
    for (i=1; i<nL+3; i=i+nL+2){
       if(Campo[lin][col]=='*')   {A--;}
                               }
   
    for(i=1; i<nC+3; i=i+nC+2){
       if (Campo[lin][col]=='*')   {A--;}
                              }
         
return A;
}

/*criação de lista*/
void FLVazia(TipoLista *Lista)
{
  Lista->Primeiro = (Apontador) malloc(sizeof(Celula));
  Lista->Ultimo = Lista->Primeiro;
  Lista->Primeiro->Prox = NULL;
}

/*uma maneira de verificar se a lista eh vazia*/
int Vazia(TipoLista Lista)
{
  return (Lista.Primeiro == Lista.Ultimo);
}

/*função que insere no inicio uma nova informação*/
void Insere(TipoItem x, TipoLista *Lista)
{
  Lista->Ultimo->Prox = (Apontador) malloc(sizeof(Celula));
  Lista->Ultimo = Lista->Ultimo->Prox;
  Lista->Ultimo->Item = x;
  Lista->Ultimo->Prox = NULL;
}

/*função que retira um elemento*/
void Retira(Apontador p, TipoLista *Lista, TipoItem *Item)
{
  /*  ---   Obs.: o item a ser retirado e  o seguinte ao apontado por  p --- */
  Apontador q;
  if (Vazia(*Lista) || p == NULL || p->Prox == NULL)
  { printf(" Erro  - Lista vazia ou posicao nao existe\n");
    return;
  }
  q = p->Prox;
  *Item = q->Item;
  p->Prox = q->Prox;
  if (p->Prox == NULL) Lista->Ultimo = p;
  free(q);
}

/*função para pega o primeiro numero da lista*/
int peganumero(TipoLista Lista)
{
  int a;
  Apontador Aux;
  Aux = Lista.Primeiro->Prox;
  a =Aux->Item.Chave;

return a;
}


/*funcao para criar um array bidimensional de char dinamicamente*/
char ** dynchar (int l, int c)
{
    int i,j;
    char ** m;
    m = (char **) malloc (l * sizeof (char *));
    if (m==NULL) return m;
    for(i=0; i<l; i++)
    m[i]= (char *) malloc (c * sizeof (char));
    if (m[i] == NULL){
       for (j=0; j<i ; j++) free (m[i]);
       free (m);
       return NULL;
    }
    return m;
}
   

   

int main (int argc, char *argv[])

{
 
  int Tn=0, li, co, nL, nC, nB, semente, i, j, c, d,A,N;
  int atoi(const char *nptr);
  char t='b';
  char ** Bombas;
  char ** Campo;
  srandom(semente);   /*usada para o sorteio das bombas*/
  nL = atoi(argv[1]); /* coloca no in o valor digitado no comando*/
  nC = atoi(argv[2]); /* coloca no in o valor digitado no comando*/
  nB = atoi(argv[3]); /* coloca no in o valor digitado no comando*/
  semente = atoi(argv[4]); /* coloca no in o valor digitado no comando*/
 
  Campo = dynchar ((nL+4),(nC+4));        
  Bombas= sorteiaBombas(nL, nC, nB, semente);
  contaBombas(nL, nC, Bombas);
 
   for (i=3; i<nL; i++)
     for (j=3; j<nC; j++)
        Campo[nL][nC]='*';
       
 
  /*se houver algum problema na execucao do comando volta*/
  if(argc < 4) {
  printf("Uso: %s <nL> <nC> <nB> <semente>\n",argv[0]);
  return 1;
               }
              
  /*comandos necessaris para lista*/
 TipoLista lista;
  TipoItem item;
  TipoItem oi,ja;
  Apontador p;
  FLVazia(&lista);
  
 /*enquanto o jogador nao digitar f o jogo continua*/
  while(t!='f')
  {
  printf  ("Faça sua jogada deste modo para abrir uma posicao faça a linha coluna, para voltar uma jogada digite v e para finalizar o programa digite f");
  scanf("%c",t);
 
  /*se a jogada for de abrir uma posicao esta eh inserida na lista e as posições abertas */
  if (t=='a'){
     scanf ("%d %d",c,d);
     oi.Chave=c;
     ja.Chave=d;
     Insere(ja, &lista);
     Insere(oi, &lista);
     N= abrePosicao(nL, nC, Bombas, Campo, c, d);
     Tn=Tn+N;
     printf ("posicoes abertas nesta jogada: %d",N);
     printf ("total de posicoes abertas: %d",Tn);
              }
  /*se voltar a jogada é pego na lista o ultimo abre e fechada a posicao*/           
  if (t=='v'){
     li= peganumero (lista);
     Retira(p, &lista, &item);;
     co= peganumero (lista);
     Retira(p, &lista, &item);;
     A = fechaPosicao(nL, nC, Campo, li, co);
     Tn=Tn-A;
     printf ("posicoes fechadas nesta jogada: %d",A);
     printf ("total de posicoes abertas: %d",Tn);
             }
           
  imprimeCampoMinado (nL, nC, Campo); /*imprime o campo minado*/
  }        
 
  /*da free na lista*/
  while (Vazia(lista)!='1' || p == NULL!='1' || p->Prox == NULL!='1') {
  Retira(p, &lista, &item);;
}
 
  free (Bombas);
  free(Campo);
  return 0;
}
line 40 [Warning] initialization makes pointer from integer without a cast
line 230 conflicting types for 'dynchar'
line 40 previous implicit declaration of 'dynchar' was here

jus these problems now , how do i solve them ??

thanks for all the help man
 
Última edição:
Podes deitar fora a detecção de colisões de bombas se percorreres o campo posição a posição e fazeres o sorteio:

-Arranjas uma variável Z, dependente da dificuldade;

-Para uma dada posição N geras um nº aletaório entre A e B; (A<Z<B)
-Se Random# for < Z metes uma mina na posição N;
-Avanças para a próxima posição e repetes até chegares ao fim.


Cumprimentos
 
srand

Boa noite.
O programa foi compilado com sucesso mas dá uma mensagem de erro a dizer que no random a semente está a ser usada sem ser inicializada
srand(semente);
 
Back
Topo