Gerador de Números Randômicos

Neste artigo mostro como criar um gerador de números randômicos, em Windows Forms, usando a linguagem C#. Como sempre o código-fonte estará disponível ao final do artigo.

Introdução

A classe Random, do .NET é muito útil quando queremos gerar números pseudo-randômicos. Podemos gerar números randômicos chamando o método Random, que aceita como parâmetro o valor inicial, valor final, ambos, ou nenhum parâmetro. Dessa forma conseguimos usar estes números em todo o tipo de sorteios ou mesmo testes. O exemplo criado será o mesmo do site Random.org.

Projeto

Criei o projeto em Windows Forms e fiz o seguinte layout.

Layout

Chamei o evento KeyPress dos textboxes para bloquear o que não for números de 0 a 9, conforme o código a seguir.

private void txtValorMinimo_KeyPress(object sender, KeyPressEventArgs e)
 {
 e.Handled = e.KeyChar < 48 || e.KeyChar > 57;
 }

 private void txtValorMaximo_KeyPress(object sender, KeyPressEventArgs e)
 {
 e.Handled = e.KeyChar < 48 || e.KeyChar > 57;
 }

O Problema

Enfrentei um problema que depois descobri que muita gente enfrenta quando resolve usar a classe Random: quando você cria uma instância dessa classe, chama o método Next e passa como parâmetro um valor (pode ser mínimo ou máximo, tanto faz), o método sempre irá retornar o mesmo valor, a cada vez que o código for executado. Isso acontece porque a cada instância é chamado o mesmo método, passando o mesmo valor, chamado de seed, e dessa forma o retorno inicial sempre será o mesmo.

A Solução

Descobri como resolver isso neste link (os créditos do código abaixo são para o autor da 1ª resposta do link), muito bem explicado por sinal. Resumindo será necessário criar uma classe estática, dessa forma a classe Random nunca será instanciada.

Primeiro crie a classe Random e também um objeto auxiliar, ambos estáticos.


private static Random random;
private static object syncObj = new object();

E agora vem o método, também estático, que irá retornar o número randômico, e aceita dois parâmetros, o valor mínimo e o máximo, respectivamente. Confira o código.


private static int GerarNumeroRandomico(int valorMinimo, int valorMaximo)
 {
 lock (syncObj)
 {
 if (random == null)
 random = new Random();
 return random.Next(valorMinimo, valorMaximo);
 }
 }

Basicamente é usado a palavra reservada lock, que garante que um thread não entre em conflito com outro thread, dessa forma é garantido que será usada um e somente um thread para realizar o processamento do que estiver dentro de lock. Se outro thread tentar entrar desse pedaço de código ela irá esperar, até que o objeto seja liberado (ao sair de dentro do conteúdo de lock). Mais sobre Threading no artigo oficial da MSDN.

Dentro de lock é instanciado o objeto random e o mesmo é retornado chamando o método Next, responsável por gerar o número randômico, recendo como parâmetro os valores inicial e final, passados anteriormente ao método.

Execução

if (!String.IsNullOrEmpty(txtValorMinimo.Text) && !String.IsNullOrEmpty(txtValorMaximo.Text))
 {
 int numeroGerado = GerarNumeroRandomico(Convert.ToInt32(txtValorMinimo.Text), Convert.ToInt32(txtValorMaximo.Text));
 lblResultado.Text = numeroGerado.ToString();
 }
 else
 MessageBox.Show("Preencha os campos com números de 1 a 100!");

Rode a aplicação, coloque os valores, iniciais e finais, e clique no botão, note que sempre será gerado um número aleatório, sem seguir uma sequência pré-definida.

random01random02random03

Pode acontecer de o mesmo número aparecer em um intervalo pequeno de tempo, principalmente se o seu intervalo de valores for pequeno (1 a 10 por exemplo), mas isso estatisticamente é passível de ocorrer. E ocorre também porque como foi escrito no início deste artigo o número é pseudo-randômico, ou seja, não é 100% randômico.

É isso, acredito que o artigo possa ser útil, comentem o que acharam. O código-fonte deste projeto se encontra neste link.

Fontes de Consulta: Stack Overflow e Random.org, além é claro de outros links postados no decorrer do artigo.

Obrigado e até o próximo artigo.

Expresse sua opinião!

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s