Solucionado (ver solução)
Solucionado
(ver solução)
2
respostas

Sobre Aleatoriedade

Ola, estou resolvendo um problema que envolve um cavalo em um tabuleiro, mas a posicao inicial dele eh aleatoria, quando eu rodo o codigo no Codeblocks GNU ele fica na posicao aleatoria, mas em outros lugares como Online C Compliler ele fica parado na posicao 1.1

Peco tambem avaliacao do que poderia ser otimizado no codigo, ele esta lento demais. Segue abaixo:

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


int tabuleiro[8][8];
int pecas = 8;



void inicia_tab(){
for(int i = 0; i < 8; i++){
    for(int j = 0 ; j < 8; j++){
        tabuleiro[i][j] = 0;
    }

}
}


void imprime_tab(){
for(int i = 0; i < 8; i++){
    for(int j = 0 ; j < 8; j++){
        printf("[%d]", tabuleiro[i][j]);
    }
    printf("\n");

}}

void inimigos(){
    srand(time(0));
    int aleY = rand() % 8;
    int aleX = rand() % 8;
    if (tabuleiro[aleX][aleY] == 0){
        tabuleiro[aleX][aleY] = 1;
    }
    else{
        pecas++;
    }

}

void cavalo(){
    int cavX, cavY;
    while (tabuleiro[cavX][cavY] != 0){
        srand(time(0));
        cavY = rand() % 8;
        cavX = rand() % 8;

    }
    tabuleiro[cavX][cavY] = 5;
}


void comer(){
    for(int i = 0; i < 8; i++){
        for(int j = 0 ; j < 8; j++){
            if(tabuleiro[j][i] == 5)
                {
                    printf("O cavalo esta no %d %d\n", j+1,i+1);



                }
            }

}}

int main()
{   //int aux = 0;
    printf("Pode demorar ate 13 segundos \n\n");
    inicia_tab();
    while (!pecas == 0){
      inimigos();
      pecas--;}
    cavalo();
    imprime_tab();
    printf("\n");
    comer();

}
2 respostas
solução!

Olá, Renan. Tudo bom?

Antes de tudo, uma revisada em seu código:

Na função cavalo(), seu programa usa as variáveis cavX e cavY sem antes as iniciar. Será que era isso mesmo o que queriamos escrever?

void cavalo() {    
    int cavX, cavY;
    while (tabuleiro[cavX][cavY] != 0) {
        srand(time(0));
        cavY = rand() % 8;
        cavX = rand() % 8;
    }
    tabuleiro[cavX][cavY] = 5;
}

Em C, utilizar uma variável sem a iniciar significa que ela possuirá um valor aleatório. Como seu código acessa endereços de uma matriz, é bem possível que o seu programa tente acessar um endereço de memória de outro programa e, deste modo, o sistema operacional finaliza seu programa.

Podemos trocar a função para:

void cavalo() {
    int cavX, cavY;

    do {
        srand(time(0));
        cavY = rand() % 8;
        cavX = rand() % 8;
    } while (tabuleiro[cavX][cavY] != 0);

    tabuleiro[cavX][cavY] = 5;
}

Seu código chama o srand em vários momentos. Você pode "semear" (seed) o gerador de números randômicos somente uma vez, no início do seu método main:

int main()
{
    srand(time(0));
    ...
}

Invocar o srand várias vezes não necessariamente aumenta a aleatoriedade do seu código e, deste modo, você arrisca cometer um erro como foi na função cavalo():

srand(time(0));
cavY = rand() % 8;
cavX = rand() % 8;

Você executa este código em um laço while. Mas, a função time retorna o número de segundos desde o dia 01/01/1970. Perceba que, dentro do mesmo segundo, você vai alimentar o gerador de números aleatórios sempre com o mesmo valor!

A mesma coisa vale para o código abaixo:

while (!pecas == 0) {
    inimigos();
    pecas--;
}

Como em inimigos() você dá um srand(time(0)); e esta função é executada em um laço while, mais uma vez, você fica preso no mesmo valor por 1 segundo!

Beleza? Então, resumindo:

  • Cuidado ao utilizar variáveis não inicializadas;
  • Invocar srand(time(0)); várias vezes exige bastante atenção;
  • Alimentar o gerador de números randôminos logo no começo da aplicação é uma boa ideia;

Eu fiz estas alterações e, agora que não temos o programa travado nos mesmos valores por 1 segundo, a aplicação é executada de forma muito mais veloz! Executei o programa no Online C Compiler e a aleatoriedade voltou!

Confesso que não investiguei a fundo a razão dele sempre retornar (1,1) em seu código original, mas, os pontos que sinalizei causam bugs bizarros! Em especial, estes compiladores online costumam ter implementações diferentes para funções como rand e time, além de um comportamento diferente quando você tenta usar uma variável não inicializada.

Tudo bem? Esclareci sua dúvida?

Para não ficar dúvida, subi aqui no github o código modificado.

Esclareceu e ajudou muito. Obrigado :)

Quer mergulhar em tecnologia e aprendizagem?

Receba a newsletter que o nosso CEO escreve pessoalmente, com insights do mercado de trabalho, ciência e desenvolvimento de software