Jogo de dados em C#


Olá, bem vindos a mais um tutorial aqui o blog! Hoje vou mostrar a vocês como fazer uma aplicação simples em formulário com Visual Studio, de um jogo de dados para dois jogadores a pedido da seguidora do C#ompilemos Fácil e do nosso canal no Youtube: @tassianamdiniz !

O resultado final será mais ou menos este aqui:




Existem dois botões para jogar: do jogador 1 e do jogador 2, quando um dos jogadores pressiona seu botão em sua respectiva vez será sorteado um valor aleatório do dado. Quem tirar o maior valor vence a vez e seus pontos serão contabilizados a cada rodada. A vez pode ser reiniciada ao pressionar o botão "Reiniciar".

Design do formulário:
Para começar o tutorial abra seu Visual Studio e cria uma aplicação do tipo "WindowsForms" com o nome de "Jogo_Dado".
Redimensione o tamanho do formulário a seu gosto e coloque uma cor de fundo a ele, se desejar.
Agora vamos adicionar as pictures boxes responsáveis por mostrar as imagens do dado: crie uma picturebox com o nome "pb_1" e a posicione no local do formulário que desejar. Duplique essa picturebox e a chame de "pb_2" e também a posicione onde achar melhor.

Agora vamos importar as imagens dos dados para o projeto: Você pode escolher as imagens que desejar, mas caso queira usar as que eu utilizei na minha aplicação, baixe o pacote com as imagens clicando aqui.
Caso tenha baixado as imagens do link acima, após baixar a pasta descompacte-a. 

Para importar as imagens vá em "Solution Explorer" (no canto superior direito da tela) >> "Properties" >> clique o lado direito do mouse vá à opção "Open":


Na janela que abrir vá até a opção "Resourcers":


E agora vá até a opção "Add Resource >> Add Existing file":


E importe as imagens dos dados:


Volte para o formulário e coloque como imagem das pictureboxes a imagem "_0" que é esta imagem do dado sem os valores.

Agora crie dois botões um com o nome de "btn_1" e outro chamado "btn_2", com texto "Jogar" do tamanho que você preferir e os posicione abaixo das pictureboxes.

Crie também um terceiro botão com o nome de "btn_reiniciar" com o texto "Reiniciar!" e tamanho que preferir, também posicionado ao seu gosto no formulário.

Após fazer isso, crie duas labels, uma com o nome "lbl_1" e outra chamada "lbl_2", com o texto "Pontos: " e tamanho e cor que preferir. Posicione essas labels acima das pictureboxes.
Crie uma outra label com o nome "lbl_vencedor" para mostrar quem ganhou a vez, com o texto "Vencedor: " e tamanho e cor que preferir. Posicione essa label onde quiser.
Por fim, crie mais duas labels com tamanho e cor que você desejar com os textos "Jogador 1" e "Jogador 2" e as posicione abaixo das picureboxes para indicar quem são os jogadores.

Por fim, seu formulário deve estar mais ou menos assim:




Variáveis:
Agora com o formulário praticamente pronto, pressione F7 em seu teclado para abrir o código do mesmo.
Vamos iniciar criando nossas variáveis:

Crie 6 variáveis do tipo inteiro: "pontosJogador1", "pontosJogador2", "jogadaJogador1", "jogadaJogador2", "nr" e "cliques".

As variáveis "pontosJogador1"e "pontosJogador2" vão guardar os valores dos pontos dos jogadores conforme eles forem ganhando as rodadas.
As variáveis jogadaJogador1" e "jogadaJogador2" vão guardar os valores dos pontos nos dados na jogada atual.
A variável "nr" vai armazenar o valor aleatório que será sorteado no dado e a variável "cliques" irá gerenciar a quantidade de cliques nos botões de "Jogar" para saber se acabou a rodada ou não.

Agora crie duas variáveis do tipo "bool", uma chamada "vezJogador1" que vai gerenciar se é vez do jogador 1 ou 2 (inicie-a em true) e outra chamada "fimDeJogo" que irá definir se o jogo se encerrou.

Também crie um array do tipo "Image" com tamanho 7 chamado "imagensDado" para armazenar as imagens possíveis do dado.

Por fim, instancie a classe "Random" para gerar o valor aleatório e dê o nome dessa instância de "rdn":




Iniciando recursos e trocando a vez:
Vamos agora criar um método que coloque as imagens importadas do dado dentro do array, para isso, crie o método sem retorno com o nome de "IniciarImagens", bastando acessar o array individualmente pelo índice e adicionar em ordem crescente as imagens, conforme imagem abaixo:



*Existe um jeito mais prático de adicionar as imagens no array através de um dicionário, porém eu não quis complicar por se tratar de poucas imagens, mas caso queira conhecer o jeito alternativo, veja neste tutorial!

Com as imagens dentro do array, vamos agora criar um método que "troque" a vez dos jogadores.
Para isso crie um novo método sem retorno com o nome de "TrocarTurno" e dentro dele apenas faça com que a variável "vezJogador1" receba o seu inverso:

Após tudo isso, criaremos dois métodos para gerenciarmos os botões dos jogadores, pois não queremos que o jogador 1 possa apertar o botão do jogador 2 em sua vez e vice-versa. Também gostaria de gerenciar o botão de "reiniciar" pois ele só poderá ser apertado se os dois jogadores já tiverem jogado.

Para isso, vamos criar dois métodos sem retorno: um chamado "AtualizarBotao" e outro chamado "CorBotao".

Dentro do método "AtualizarBotao" faça com que o botão "btn_1" do jogador 1 só possa estar habilitado se for a vez dele, ou seja, se "vezJogador1" for true e se o jogo não acabou, se "fimDeJogo" for false.
Faça a mesma validação para "btn_2" mas se "vezJogador1" é false.
Para "btn_Reiniciar" faça ele ficar habilitado apenas se "fimDeJogo" for true.

Após essas três validações, chame o método "CorBotao".

Dentro do método "CorBotao" troque a cor dos três botões de acordo se estão habilitados ou não: caso estiverem habilitados eles recebem a cor "Red" (vermelha), do contrário, recebem a cor branca (White):



Por fim, chame os métodos "IniciarImagens" e "AtualizarBotao" no construtor do formulário:

Sorteando valor e mudando imagem do dado:
Após os procedimentos acima, vamos criar um método que mostre a imagem do dado conforme o valor aleatório que será sorteado e que estará armazenado na variável "nr".

Crie o método sem retorno com o nome de "MudarImagem" e verifique se "vezJogador1" está true, se estiver, a picturebox "pb_1" recebe o valor de imagem do array "imagensDado" na posição do índice de "nr".
Caso a variável "vezJogador2" esteja false, quem recebe este valor é a picturebox "pb_2":

Após criar este método, crie dois novos métodos também sem retorno, um com o nome de "SortearValor" e outro com o nome de "FinalizarRodada".

O método "SortearValor" obviamente ficará responsável por sortear um valor aleatório para o dado, então apenas faça com que "nr" receba o valor de rdn.NextDouble convertido para inteiro, multiplicando esse valor por 10 (para impedir que seja sorteado um valor decimal) e usando o módulo de 6, limitando para que seja sorteado apenas valores de 0 a 6. Também incremente essa variável para impedir que seja sorteado o valor 0, limitando os valores de 1 a 6. Depois chame os métodos "MudarImagem" e  "FinalizarRodada, respectivamente":



**Outra forma de randomizar um número será através do comando: nr = rdn.Next(1, 7); então qualquer uma das duas formas estaria correto.

Finalizando rodada e mostrando vencedor:
Para finalizar a rodada, precisamos antes criar mais dois métodos sem retorno: um chamado "MostrarVencedor" e outro chamado "MostrarPontos":

Dentro do método "MostrarVencedor" apenas faça com que a variável "fimDeJogo" fique true, a label "lbl_vencedor" receba o texto conforme o jogador que ganhou, ou seja, se "jogadaJogador1" for maior que "jogadaJogador2" o texto será "Jogador 1", se não então "jogadaJogador2" é maior que "jogadaJogador1", então o texto será "Jogador 2", do contrário, o texto será "Empate!".
Utilize o método "string.Format() para realizar essas validações.

Também dentro desse método aumente o ponto do jogador vencedor, ou seja, se "jogadaJogador1" for maior que "jogadaJogador2" incremente a variável "pontosJogador1", do contrário, incremente a variável "pontosJogador2".

Depois dessas validações chame o método "MostrarPontos":


Agora dentro do método "MostrarPontos" apenas faça com que a label "lbl_1" mostre o texto "Pontos" e o valor de "pontosJogador1" convertido para string. A label "lbl_2" deve mostrar o valor de "pontosJogador2":



Finalmente volte para o método "FinalizarRodada" para implementá-lo:
Faça com que a variável "jogadaJogador1" receba o valor de "nr" se "vezJogador1" for true, caso for false, faça com que "jogadaJogador2" receba esse valor.

Verifique se "cliques" é igual a 2, caso for chame o método "MostrarVencedor", caso não, chame o método "TrocarTurno".

Após essa verificação chame o método "AtualizarBotao":


Clicando nos botões:
Por fim, temos que criar os métodos que serão responsáveis por fazer com que cliquemos nos botões e possamos jogar de fato.
Primeiro vamos criar o método para clicar nos dois botões de jogar: Crie um método sem retorno com o nome de "Clicar" e contendo dois parâmetros: um do tipo "object" que você vai chamar de "objeto" e outro do tipo "EventsArgs" que você simplesmente chama de "e".
Dentro desse método você apenas incrementa a variável "cliques" e chama o método "SortearValor":


Salve o código (CTRL+S) e volte ao formulário: clique com o lado esquerdo do mouse sobre os dois botões "jogar" e vá até a janela de "Events" (o símbolo do raio) e em "Click" selecione o método "Clicar", assim quando clicarmos nesses botões eles vão chamar o evento "Clicar":



Volte para o seu código para que criemos o método para o botão de "reiniciar". Também o declare sem retorno, com o nome de "Reiniciar" e com os mesmos parâmetros que o método "Clicar".
Dentro desse método faremos com que todo o jogo se resete, ou seja, faça a variável "fimDejogo" voltar a ser false, "jogadaJogador1", "jogadaJogador2" e "cliques" fiquem igual a zero, a "lbl_vencedor" volte a mostrar o texto "Vencedor: ", "pb_1" e "pb_2" tenham a imagem do dado sem os valores, ou seja, a imagem do array "imagensDado" no índice zero, e por fim, chame o método "AtualizarBotao":




Para finalizar a aplicação, salve-a (CTRL+S), volte ao formulário, clique no botão "Reiniciar" e na janela de "Events >> Click" selecione o método "Reiniciar" para ele ser chamado assim que esse botão for pressionado:


E pronto, está finalizado!

Finalização:
Então aqui chega o final de mais um tutorial aqui no blog! Espero que tenham gostado, e se quiserem baixar o jogo, basta clicar aqui.
E faça como a @tassianamdiniz, peça um tutorial para ser postado aqui no blog ou lá no canal do YouTube, basta entrar em contato através dos comentários aqui do blog ou do meu instagram: @mayszleone !


Código do projeto (apenas o que foi postado no tutorial, sem o design)



using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace Jogo_dado { public partial class Form1 : Form { private int pontosJogador1, pontosJogador2, jogadaJogador1, jogadaJogador2, nr, cliques; private bool vezJogador1 = true, fimDeJogo; private Image[] imagensDado = new Image[7]; private Random rdn = new Random(); public Form1() { InitializeComponent(); IniciarImagens(); AtualizarBotao(); } private void IniciarImagens() { imagensDado[0] = Properties.Resources._0; imagensDado[1] = Properties.Resources._1; imagensDado[2] = Properties.Resources._2; imagensDado[3] = Properties.Resources._3; imagensDado[4] = Properties.Resources._4; imagensDado[5] = Properties.Resources._5; imagensDado[6] = Properties.Resources._6; } private void TrocarTurno() { vezJogador1 = !vezJogador1; } private void AtualizarBotao() { btn_1.Enabled = vezJogador1 && !fimDeJogo; btn_2.Enabled = !vezJogador1 && !fimDeJogo; btn_reiniciar.Enabled = fimDeJogo; CorBotao(); } private void CorBotao() { btn_1.BackColor = btn_1.Enabled ? Color.Red : Color.White; btn_2.BackColor = btn_2.Enabled ? Color.Red : Color.White; btn_reiniciar.BackColor = btn_reiniciar.Enabled ? Color.Red : Color.White; } private void Clicar(object objeto, EventArgs e) { cliques++; SortearValor(); } private void SortearValor() { nr = (int)Math.Truncate((rdn.NextDouble() * 10) % 6); nr++; MudarImagem(); FinalizarRodada(); } private void MudarImagem() { if (vezJogador1) pb_1.Image = imagensDado[nr]; else pb_2.Image = imagensDado[nr]; } private void FinalizarRodada() { if (vezJogador1) jogadaJogador1 = nr; else jogadaJogador2 = nr; if (cliques == 2) MostrarVencedor(); else TrocarTurno(); AtualizarBotao(); } private void MostrarVencedor() { fimDeJogo = true; lbl_vencedor.Text += " " + string.Format(jogadaJogador1 > jogadaJogador2 ? "Jogador 1" : (jogadaJogador1 < jogadaJogador2 ? "Jogador 2" : "Empate!")); if (jogadaJogador1 > jogadaJogador2) pontosJogador1++; else if (jogadaJogador1 < jogadaJogador2) pontosJogador2++; MostrarPontos(); } private void MostrarPontos() { lbl_1.Text = "Pontos: " + pontosJogador1.ToString(); lbl_2.Text = "Pontos: " + pontosJogador2.ToString(); } private void Reiniciar(object objeto, EventArgs e) { fimDeJogo = false; jogadaJogador1 = jogadaJogador2 = cliques = 0; lbl_vencedor.Text = "Vencedor: "; pb_1.Image = pb_2.Image = imagensDado[0]; AtualizarBotao(); } } }

Comentários