Ir para conteúdo

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

Wellington09

[Resolvido] gerador de numeros aleatorios

Recommended Posts

Pessoal eu tenho a seguinte função

 

function jogo($qt_numero){
	for($cont=1; $cont <= $qt_numero; $cont++){
		$sorteado = rand(1,10);
		echo ("$sorteado\n");
	}
}
jogo(5);

O que eu preciso fazer é que nesses 5 numeros que aparecem na pagina quando dou um F5, que eles não se repitam.

ex:

Primeira tentativa apareceu: 9 5 3 6 2 beleza não repetiu, F5

Segunda tentativa apareceu: 1 8 1 5 1 repetiu o número 1 três vezs, F5

Terceira tentativa apareceu: 5 3 2 2 6 repetiu o número 2 duas vezs, F5

Quarta tentativa apareceu: 3 8 1 2 8 repetiu o número 8 duasvezs, F5

Quinta tentativa apareceu: 7 5 1 2 1 repetiu o número 1 duas vezs, F5

Sexta tentativa apareceu: 5 10 9 2 7 beleza não repetiu

 

Resolvendo está parte de não repetir os numeros eu preciso que ele gere 8 jogos de 5 numeros entre 1 e 10 sem nunca repetir os numeros que já foram feito pelo proprio random, para que eu não precise ficar apertando F5 toda hora ex:

5 10 9 2 7

9 5 3 6 2

1 8 2 5 4

5 3 9 2 6

3 10 1 2 8

7 5 8 2 1

3 5 9 2 4

10 6 1 2 7

Compartilhar este post


Link para o post
Compartilhar em outros sites

Vai colocando os numeros sorteados num array. Aí depois você checa com a função in_array() se o numero não foi registrado, caso ja tenha sido você chama a propria função novamente (recursividade) e da um break.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Wellington,

 

Que tal remover o rand e o loop ?

 

Veja:

/**
* Imprime números aleatórios
* @param integer $qtd Quantidade de números gerados
* @param integer $min Menor número que será gerado
* @param integer $max Maior número que será gerado
*/
function jogo( $qtd , $min = 0 , $max = 10 ){
$numeros = range( $min , $max > $qtd ? $max : $qtd ); //gera uma sequencia 
shuffle( $numeros ); //embaralha a sequencia
echo implode( PHP_EOL , array_slice( $numeros , 0 , $qtd ) ) , PHP_EOL; //mostra apenas a quantidade desejada
}

jogo( 5 );

Compartilhar este post


Link para o post
Compartilhar em outros sites

Então João é isso mesmo que estou precisando só que o problema é que não estou entendendo uns comandos que você colocou e não quero fazer CTRL+C e CTRL+V to tentando entender oque você fez mas eu estou tentando trabalhar aqui com o in_array que o lucas falou , por enquanto eu to parado aqui.

function jogo($qt_numero,$qt_jogos){
	for($jogos=1; $jogos <= $qt_jogos; $jogos++){
		for($cont=1; $cont <= $qt_numero; $cont++){
			$sorteado = rand(1,10);
			echo ("$sorteado\n");
		}
		echo "<br />";
	}
}
jogo(5,10);

ta gerando 10 jogos em uma sequencia de 5 numeros mas eu to tentando trabalhar em cima disso agora:

$teste= array("1", "2"); 
if (in_array("2", $teste)) { 
    echo "repetido";
}
para não repetir mais os numeros como no seu exemplo João

 

Eu nunca trabalhei com in_array por isso to tentando entender, como estou tentando entender o seu codigo tb.

ex:

echo implode( PHP_EOL , array_slice( $numeros , 0 , $qtd ) ) , PHP_EOL; //mostra apenas a quantidade desejada

Compartilhar este post


Link para o post
Compartilhar em outros sites

...

 

for($cont=1; $cont <= $qt_numero; $cont++){

$sorteado = rand(1,10);

if(in_array($sorteado,$numsort){

$cont = $cont - 1;

}else{

$numsort[$cont] = $sorteado;

echo ("$sorteado\n");

}

}

 

...

Seria algo do tipo?

Compartilhar este post


Link para o post
Compartilhar em outros sites

Então João é isso mesmo que estou precisando só que o problema é que não estou entendendo uns comandos que você colocou e não quero fazer CTRL+C e CTRL+V to tentando entender oque você fez

Lendo a documentação você consegue entender bem. Veja:

 

http://www.php.net/implode

http://www.php.net/array_slice

http://www.php.net/shuffle

 

PHP_EOL é End Of Line, ou seja, \n em sistemas Unix e \r\n em Windows

 

 

É bem mais simples e eficiente que executar loops com rand().

Compartilhar este post


Link para o post
Compartilhar em outros sites

Com a ajuda da galera do forum consegui chegar onde queria.

O problema é que as vzs repete uma sequencia que já foi feita , as vzs até repete por 2 vzs.

ex:

01 02 05

01 03 04

02 03 04

01 02 05 = poderia ter feito / 02 04 05 que não existe ainda e mesmo assim ele repetiu uma sequencia que já foi feita

03 04 05

 

copia e cola ai pra vcs verem, as vzs não vem nada repetido e tem vzs que vem repetidos.

 

function jogo($qt_numero,$qt_jogos){
	$sorteados = array();
    	for($jogos=1; $jogos <= $qt_jogos; $jogos++){
        	for($numero=1; $numero <= $qt_numero; $numero++){                                                               
            	$numero_sorteado = str_pad(rand(1, 5), 2, '0', STR_PAD_LEFT);
                #laço que vai controlar se o numero sorteado já existe
                while( verificaNumeroRepetido( $numero_sorteado, $sorteados ) ){
                	$numero_sorteado = str_pad(rand(1, 5), 2, '0', STR_PAD_LEFT);
                }
                $sorteados[$numero] = $numero_sorteado;
            }
            #função para imprimir o jogo
            imprimirJogo( $sorteados );                     
		}
}
function verificaNumeroRepetido( $numero, $array ){
	if( in_array( $numero, $array ) )
    	return true;
        return false;
}
        
function imprimirJogo( $array_sorteio ){
	#ordenar o array em ordem crescente
    sort($array_sorteio);
    foreach( $array_sorteio as $numero )
   		echo $numero . " ";
        echo "<br />";
}

jogo(3,5);

Compartilhar este post


Link para o post
Compartilhar em outros sites

Antes de dar um echo joga o Jogo inteiro para dentro de um array...

Dai no próximo jogo você verifica com o in_array...

Se não tiver o jogo joga ele pra dentro do array...

Dai no próximo jogo você verifica com o in_array...

Se não tiver o jogo joga ele pra dentro do array...

Se tiver o jogo não joga pro array...

Depois tu exibe os jogos pela variavel que tu armazenou os jogos no array...

Compartilhar este post


Link para o post
Compartilhar em outros sites

realmente para não repetir terá que armazenar em algum lugar as sequencias e antes de escrever ver se já existe

Compartilhar este post


Link para o post
Compartilhar em outros sites

terá que armazenar em algum lugar

 

Ou fazer como sugeri no post #3 e avalizado pelo Beraldo no post #7.

 

De fato, a melhor solução é a apresentada no post #3, se utilizar um loop com rand() o número de iterações tende crescer muito conforme a quantidade de números desejados, principalmente se a faixa de números aleatórios for próxima ao total de números, veja:

 

$numeros	= array();
$total 	= 5;
$min 	= 1;
$max 	= 10;

while ( count( $numeros = array_unique( $numeros ) ) < $total ){
$numeros[] = rand( $min , $max );
echo 'Dando uma volta' , PHP_EOL;
}

var_dump( $numeros );

 

A saída poderá ser:

 

Dando uma volta

Dando uma volta

Dando uma volta

Dando uma volta

Dando uma volta

Dando uma volta

array(5) {

[0]=>

int(1)

[1]=>

int(7)

[3]=>

int(9)

[4]=>

int(4)

[5]=>

int(3)

}

 

Perceba que foram necessárias 6 voltas no loop para conseguir 5 números únicos, agora, um caso problemático:

 

$numeros	= array();
$total 	= 20;
$min 	= 1;
$max 	= 20;
$voltas 	= 0;

while ( count( $numeros = array_unique( $numeros ) ) < $total ){
$numeros[] = rand( $min , $max );
++$voltas;
}

var_dump( count( $numeros ) , $voltas );

 

Perceba agora a proximidade entre total de números aleatórios e faixa de números que será gerada, o resultado é:

int(20)

int(87)

 

Durante os testes houveram situações em que foram necessárias 103 voltas para se conseguir gerar 20 números.

 

$numeros	= array();
$total 	= 5;
$min 	= 1;
$max 	= 10;

while ( count( $numeros = array_unique( $numeros ) ) < $total ) $numeros[] = rand( $min , $max );

var_dump( $numeros );

 

A implementação acima funciona é claro, mas definitivamente não é eficiente.

 

Quando se trabalha com range( $min , $max , $step ) é gerada uma matriz com a faixa de números desejada:

 

$numeros = range( 1 , 10 );
print_r( $numeros );

 

A saída:

Array

(

[0] => 1

[1] => 2

[2] => 3

[3] => 4

[4] => 5

[5] => 6

[6] => 7

[7] => 8

[8] => 9

[9] => 10

)

 

Como estamos com uma matriz, podemos utilizar a função shuffle( &$array ) para embaralhar a matriz:

$numeros = range( 1 , 10 );
shuffle( $numeros );

print_r( $numeros );

 

A saída:

Array

(

[0] => 6

[1] => 5

[2] => 10

[3] => 3

[4] => 9

[5] => 8

[6] => 2

[7] => 7

[8] => 4

[9] => 1

)

 

Com a matriz embaralhada, pegamos só a quantidade de elementos que precisamos com a função array_slice( $array , $offset , $length ):

$numeros = range( 1 , 10 );
shuffle( $numeros );

print_r( array_slice( $numeros , 0 , 5 ) );

 

A saída:

Array

(

[0] => 3

[1] => 10

[2] => 7

[3] => 6

[4] => 9

)

 

Como não usamos loops o desempenho é muitas vezes maior que o concorrente utilizando loop.

Compartilhar este post


Link para o post
Compartilhar em outros sites

boa tarde, poderia me informar como passo isso tudo

 

Array ( [0] => 5 [1] => 6 [2] => 7 [3] => 8 [4] => 9 [5] => 1 [6] => 3 [7] => 2 [8] => 4 )

 

que é gerado pelo

 

print_r(array_slice($numeros, 0, 9));

 

pra somente

 

567891324

 

grato desde já

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.