Vinicius Rodrigues Posted June 1, 2014 at 06:28 PM Report #557825 Posted June 1, 2014 at 06:28 PM (edited) Boa tarde pessoal, é meu primeiro post, estou começando na programação, no segundo ano de faculdade, porém nunca tive contato com programação, e tenho encontrado muita dificuldade, estamos no fechamento do semestre o professor passou-nos um trabalho com o código de um jogo da velha ja esta pronto, é para nós fatorarmos, diminuir o código, são 9 botões do tipo TButton cada um deles recebe o seguinte código: NumeroVezes:=NumeroVezes + 1; Button1,Caption:= 'X'; Verificar; Como é o mesmo código para os nove só mudando o "nome do botão" pensei em criar um ActionlList com um Action que recebe o código acima e utilizá-lo associando aos 9 botões, porém feito isso não execução não funciona aonde deveria aparecer X fica em branco. Por favor me ajudem a achar o meu erro, minha inexperiência pode me levar a reprovar na faculdade. Grato Edited June 1, 2014 at 07:00 PM by thoga31 Tags code + GeSHi
nunopicado Posted June 1, 2014 at 07:07 PM Report #557828 Posted June 1, 2014 at 07:07 PM (edited) Calma, não será por um exercício que reprovarias... 🙂 Pela descrição que dizes, eu não iria para uma Action, mas sim para um único handler para os 9 botões. Pelo que consegui perceber, o NumeroVezes é só um contador do numero de jogadas, e presumo que o "Verificar" seja para ver se o utilizador ganhou. Precisas portanto de um handler que, ao clicar num dos 9 botões, escreva X ou O, conforme o jogador activo, é isso? Imagina o seguinte handler: procedure BotaoJogo(Sender: TObject); begin end; Este é um handler típico para o Evento onclick do TButton. Reparaste no parâmetro Sender? Esse parâmetro trás com ele a indicação do botão que foi carregado para chegar ao handler. Vem como TObject, a classe raíz, pelo que ter de fazer um TypeCasting (converter) para obteres o TButton: procedure BotaoJogo(Sender: TObject); var Botao:TButton; begin Botao := Sender AS TButton; // A partir deste momento, tudo o que fizeres com o "Botao", estarás a fazer ao botão que foi clicado no tabuleiro do jogo. // Por exemplo, se quiseres por a Caption do botão clicado com um 'X', fazes: Botao.Caption := 'X'; // Não interessa qual foi clicado, desde que adiciones este handler aos TButtons todos do jogo, isto irá funcionar. end; Claro que não te basta meter o X. Tens de saber várias coisas para o processo ser correcto. Por exemplo, precisas saber o nome do botão, para saberes a posição dele: Botao.Name // Terá o nome do botão clicado E qual o jogador que está a jogar no momento: NumeroVezes // Pode indicar-te quem está a jogar, conforme seja par ou impar Estás a seguir? Dúvida até aqui? Edited June 1, 2014 at 07:09 PM by nunopicado 1 Report "A humanidade está a perder os seus génios... Aristóteles morreu, Newton já lá está, Einstein finou-se, e eu hoje não me estou a sentir bem!" > Não esclareço dúvidas por PM: Indica a tua dúvida no quadro correcto do forum.
Vinicius Rodrigues Posted June 2, 2014 at 03:54 AM Author Report #557868 Posted June 2, 2014 at 03:54 AM Bom dia Obrigado pela ajuda nunopicado. o/
Vinicius Rodrigues Posted June 3, 2014 at 03:27 AM Author Report #558024 Posted June 3, 2014 at 03:27 AM (edited) Bom dia nunopicado esse foi o código apresentado para nós fazermos a refatoração, diminuirmos o código, mas eu não sei como fazer isso, se puder ajudar agradeço. Grato. Vinicius unit UFrmJogoDaVelha; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ActnList; type TPainel = class(TForm) Button1: TButton; Button2: TButton; Button3: TButton; Button4: TButton; Button5: TButton; Button6: TButton; Button7: TButton; Button8: TButton; Button9: TButton; ActionList1: TActionList; procedure JogoNovo; procedure Verificar; procedure FormCreate(Sender: TObject); procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); procedure Button3Click(Sender: TObject); procedure Button4Click(Sender: TObject); procedure Button5Click(Sender: TObject); procedure Button6Click(Sender: TObject); procedure Button7Click(Sender: TObject); procedure Button8Click(Sender: TObject); procedure Button9Click(Sender: TObject); private { Private declarations } public { Public declarations } end; var Painel: TPainel; Botao: array[1..9] of TButton; implementation var NumeroVezes: Integer; {$R *.dfm} procedure TPainel.JogoNovo(); var M: Real; i: Integer; begin for i:=1 to 9 do Botao[i].Caption:=''; M:=Int(Random * 10); i:=StrToInt(FloatToStr(M)); Botao[i].Caption:='0'; NumeroVezes:=0; end; procedure TPainel.Verificar; label 1,2; var i: Integer; Resposta: Integer; begin if (Button1.Caption='X') and (Button2.Caption='X') and (Button3.Caption='X') then goto 1; if (Button4.Caption='X') and (Button5.Caption='X') and (Button6.Caption='X') then goto 1; if (Button7.Caption='X') and (Button8.Caption='X') and (Button9.Caption='X') then goto 1; if (Button1.Caption='X') and (Button4.Caption='X') and (Button7.Caption='X') then goto 1; if (Button2.Caption='X') and (Button5.Caption='X') and (Button8.Caption='X') then goto 1; if (Button3.Caption='X') and (Button6.Caption='X') and (Button9.Caption='X') then goto 1; if (Button1.Caption='X') and (Button5.Caption='X') and (Button9.Caption='X') then goto 1; if (Button3.Caption='X') and (Button5.Caption='X') and (Button7.Caption='X') then goto 1; repeat i:=StrtoInt(FloattoStr(Int (Random *10))) until Botao[i].Caption='' ; Botao[i].Caption:='0'; if (Button1.Caption='0') and (Button2.Caption='0') and (Button3.Caption='0') then goto 2; if (Button4.Caption='0') and (Button5.Caption='0') and (Button6.Caption='0') then goto 2; if (Button7.Caption='0') and (Button8.Caption='0') and (Button9.Caption='0') then goto 2; if (Button1.Caption='0') and (Button4.Caption='0') and (Button7.Caption='0') then goto 2; if (Button2.Caption='0') and (Button5.Caption='0') and (Button8.Caption='0') then goto 2; if (Button3.Caption='0') and (Button6.Caption='0') and (Button9.Caption='0') then goto 2; if (Button1.Caption='0') and (Button5.Caption='0') and (Button9.Caption='0') then goto 2; if (Button3.Caption='0') and (Button5.Caption='0') and (Button7.Caption='0') then goto 2; if NumeroVezes= 4 then Begin ShowMessage ('Partida Empatada'); JogoNovo; Exit; End; Exit; 1: Begin Resposta:=Application.MessageBox ('Você ganhou, quer Jogar Novamente?','Vencedor',36); if Resposta = 7 then Close; JogoNovo; Exit; End; 2: Begin Resposta:=Application.MessageBox ('Eu ganhei, quer Jogar Novamente?','Vencedor',36); if Resposta = 7 then Close; JogoNovo; Exit; End; end; procedure TPainel.Button1Click(Sender: TObject); begin NumeroVezes:=NumeroVezes + 1; Button1.Caption:= 'X'; Verificar; end; procedure TPainel.Button2Click(Sender: TObject); begin NumeroVezes:=NumeroVezes + 1; Button2.Caption:= 'X'; Verificar; end; procedure TPainel.Button3Click(Sender: TObject); begin NumeroVezes:=NumeroVezes + 1; Button3.Caption:= 'X'; Verificar; end; procedure TPainel.Button4Click(Sender: TObject); begin NumeroVezes:=NumeroVezes + 1; Button4.Caption:= 'X'; Verificar; end; procedure TPainel.Button5Click(Sender: TObject); begin NumeroVezes:=NumeroVezes + 1; Button5.Caption:= 'X'; Verificar; end; procedure TPainel.Button6Click(Sender: TObject); begin NumeroVezes:=NumeroVezes + 1; Button6.Caption:= 'X'; Verificar; end; procedure TPainel.Button7Click(Sender: TObject); begin NumeroVezes:=NumeroVezes + 1; Button7.Caption:= 'X'; Verificar; end; procedure TPainel.Button8Click(Sender: TObject); begin NumeroVezes:=NumeroVezes + 1; Button8.Caption:= 'X'; Verificar; end; procedure TPainel.Button9Click(Sender: TObject); begin NumeroVezes:=NumeroVezes + 1; Button9.Caption:= 'X'; Verificar; end; procedure TPainel.FormCreate(Sender: TObject); begin Randomize; Botao[1] :=Button1; Botao[2] :=Button2; Botao[3] :=Button3; Botao[4] :=Button4; Botao[5] :=Button5; Botao[6] :=Button6; Botao[7] :=Button7; Botao[8] :=Button8; Botao[9] :=Button9; JogoNovo; end; end. Edited June 3, 2014 at 08:17 AM by nunopicado GeShi
nunopicado Posted June 3, 2014 at 08:22 AM Report #558030 Posted June 3, 2014 at 08:22 AM (edited) Bem, a primeira coisa que te posso sugerir é que indentes correctamente o teu código... A indentação não é só uma questão de estética. Estando bem feita, facilita a leitura do código e a detecção de erros, o que ajuda tanto a ti a fazer o código, como ao professor ao lê-lo. Tenho a certeza que não queres que o professor tenha como primeiro impacto um amontoado de caracteres, em vez de um código bem estruturado. Garanto-te que a tua nota também vai depender disso. E o que é melhor, não custa nada fazer! Sobre o código propriamente dito, há aí tanto para mexer que temos de ir por fases. Começo por aquilo que já te tinha dito: O Handler dos botões. Tu tens: procedure TPainel.Button1Click(Sender: TObject); begin NumeroVezes:=NumeroVezes + 1; Button1.Caption:= 'X'; Verificar; end; procedure TPainel.Button2Click(Sender: TObject); begin NumeroVezes:=NumeroVezes + 1; Button2.Caption:= 'X'; Verificar; end; procedure TPainel.Button3Click(Sender: TObject); begin NumeroVezes:=NumeroVezes + 1; Button3.Caption:= 'X'; Verificar; end; procedure TPainel.Button4Click(Sender: TObject); begin NumeroVezes:=NumeroVezes + 1; Button4.Caption:= 'X'; Verificar; end; procedure TPainel.Button5Click(Sender: TObject); begin NumeroVezes:=NumeroVezes + 1; Button5.Caption:= 'X'; Verificar; end; procedure TPainel.Button6Click(Sender: TObject); begin NumeroVezes:=NumeroVezes + 1; Button6.Caption:= 'X'; Verificar; end; procedure TPainel.Button7Click(Sender: TObject); begin NumeroVezes:=NumeroVezes + 1; Button7.Caption:= 'X'; Verificar; end; procedure TPainel.Button8Click(Sender: TObject); begin NumeroVezes:=NumeroVezes + 1; Button8.Caption:= 'X'; Verificar; end; procedure TPainel.Button9Click(Sender: TObject); begin NumeroVezes:=NumeroVezes + 1; Button9.Caption:= 'X'; Verificar; end; Nove botões, nove handlers, e todos praticamente iguais. Só muda o botão que o chamou. Volta ao que te tinha dito no post anterior, e conseguirás converter estes nove handlers em apenas um, usando o (Sender AS TButton) em vez do nome do botão. Avisa quando estiver. PS: Só para teres uma ideia, só neste passo reduzes cerca de 62 linhas de código... Edited June 4, 2014 at 04:42 PM by nunopicado "A humanidade está a perder os seus génios... Aristóteles morreu, Newton já lá está, Einstein finou-se, e eu hoje não me estou a sentir bem!" > Não esclareço dúvidas por PM: Indica a tua dúvida no quadro correcto do forum.
Vinicius Rodrigues Posted June 4, 2014 at 03:41 AM Author Report #558158 Posted June 4, 2014 at 03:41 AM Bom dia nunopicado Consegui implementar o método como você me explicou, um método para os nove botões, como eu faço agora para excluir os 9 métodos que agora ja não preciso mais? amanhã é a entrega do trabalho e a ultima prova, sua ajuda foi muito útil, vou procurar entrar para ver a resposta antes da faculdade que começa as 19hrs horario de Brasilia nós estamos com o fuso-horário de 4hrs de diferença dai para cá. Muito Obrigado
nunopicado Posted June 4, 2014 at 07:29 AM Report #558160 Posted June 4, 2014 at 07:29 AM (edited) Os métodos a mais basta eliminar do código (não esquecer as declarações dos métodos na definição da classe). Há muito mais a optimizar aí... Pena o prazo ser curto. - Podes remover a actionlist que não estás a usar - Onde usas o Random, basta usar Random(9)+1 que já recebes um número inteiro de 1 a 9, sem precisares de todas aquelas conversões - O array de botões é completamente inútil. Podes fazer os ciclos directamente nos botões usando o método FindComponent que te devolve um objecto com o nome que lhe passes por parâmetro - O teu algoritmo de verificação com todos aqueles ifs e gotos é possivelmente a parte do teu programa que mais precisa ser optimizada. Basta um if para cada jogador, dentro de um ciclo que percorra as possibilidades de vitória, que podem ser guardadas por exemplo num array de constantes string: Const cWins:array [1..8] of string=('123','456','789','147','258','369','159','357'); Se percorreres com um ciclo este array, e para cada uma destas posições somares as captions dos botões correspondentes (exemplo, botao1.caption + botao2.caption + botao3.caption, mais uma vez o FindComponent é precioso para isto) e verificares se é igual a 'OOO' ou 'XXX', encontras o teu vencedor. Se não for igual a nenhum destes, é porque ninguém ganhou ainda. Edited June 4, 2014 at 07:50 AM by nunopicado "A humanidade está a perder os seus génios... Aristóteles morreu, Newton já lá está, Einstein finou-se, e eu hoje não me estou a sentir bem!" > Não esclareço dúvidas por PM: Indica a tua dúvida no quadro correcto do forum.
Vinicius Rodrigues Posted June 4, 2014 at 09:58 PM Author Report #558253 Posted June 4, 2014 at 09:58 PM Boa noite nunopicado Obrigado, deu certo como você ensinou, agora o array vou tentar criar hoje no horario da prova. mais uma vez, muito obrigado.
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now