|
Inicio → WINDEV 25 → Jogo da velha (Tic-Tac-Toe) em WLanguage, utilizando Orientação a Objetos |
Jogo da velha (Tic-Tac-Toe) em WLanguage, utilizando Orientação a Objetos |
Iniciado por Boller, 17,mar. 2025 16:55 - No hay respuesta |
| |
| | | |
|
| |
Miembro registrado 4.520 mensajes |
|
Publicado el 17,marzo 2025 - 16:55 |
Boa tarde
Vou criar uma implementação do jogo da velha (Tic-Tac-Toe) em WLanguage, utilizando Orientação a Objetos (OOP) e aplicando as melhores práticas possíveis, como encapsulamento, responsabilidade única (SOLID), modularidade e código limpo. O jogo será para dois jogadores (X e O), com um tabuleiro 3x3, e verificará vitórias ou empates.
---
### Estrutura do Projeto Vamos dividir o código em classes com responsabilidades claras: - **`Celula`**: Representa uma célula do tabuleiro. - **`Tabuleiro`**: Gerencia o estado do jogo e a lógica de vitória. - **`Jogo`**: Controla a interação com o usuário e o fluxo do jogo.
---
### Passo 1: Código das Classes
1. **Classe `Celula`** Representa cada célula do tabuleiro, que pode estar vazia ou conter "X" ou "O".
```wlanguage CLASS Celula PRIVATE sValor IS string = " " // Espaço vazio por padrão PUBLIC PROCEDURE Construtor() sValor = " " END FUNCTION GetValor() IS string RETURN sValor END PROCEDURE SetValor(sNovoValor IS string) IF sValor = " " AND (sNovoValor = "X" OR sNovoValor = "O") THEN sValor = sNovoValor END END FUNCTION EstaVazia() IS boolean RETURN sValor = " " END END ``` - **Encapsulamento**: O valor é privado e só pode ser alterado por `SetValor`, com validação. - **Responsabilidade**: Gerencia apenas o estado de uma célula.
2. **Classe `Tabuleiro`** Gerencia o estado do jogo, incluindo o tabuleiro e a lógica de vitória.
```wlanguage CLASS Tabuleiro PRIVATE arrCelulas IS array of Celula[3,3] // Matriz 3x3 PUBLIC PROCEDURE Construtor() LOCAL i, j IS int FOR i = 0 TO 2 FOR j = 0 TO 2 arrCelulas[i,j] = NEW Celula() END END END FUNCTION Jogar(nLinha IS int, nColuna IS int, sJogador IS string) IS boolean IF nLinha >= 0 AND nLinha <= 2 AND nColuna >= 0 AND nColuna <= 2 THEN IF arrCelulas[nLinha, nColuna].EstaVazia() THEN arrCelulas[nLinha, nColuna].SetValor(sJogador) RETURN True END END RETURN False END FUNCTION VerificarVitoria() IS string LOCAL i IS int sLinha, sColuna, sDiag1, sDiag2 IS string // Verifica linhas FOR i = 0 TO 2 sLinha = arrCelulas[i,0].GetValor() + arrCelulas[i,1].GetValor() + arrCelulas[i,2].GetValor() IF sLinha = "XXX" THEN RETURN "X" IF sLinha = "OOO" THEN RETURN "O" END // Verifica colunas FOR i = 0 TO 2 sColuna = arrCelulas[0,i].GetValor() + arrCelulas[1,i].GetValor() + arrCelulas[2,i].GetValor() IF sColuna = "XXX" THEN RETURN "X" IF sColuna = "OOO" THEN RETURN "O" END // Verifica diagonais sDiag1 = arrCelulas[0,0].GetValor() + arrCelulas[1,1].GetValor() + arrCelulas[2,2].GetValor() sDiag2 = arrCelulas[0,2].GetValor() + arrCelulas[1,1].GetValor() + arrCelulas[2,0].GetValor() IF sDiag1 = "XXX" OR sDiag2 = "XXX" THEN RETURN "X" IF sDiag1 = "OOO" OR sDiag2 = "OOO" THEN RETURN "O" RETURN "" END FUNCTION EstaCheio() IS boolean LOCAL i, j IS int FOR i = 0 TO 2 FOR j = 0 TO 2 IF arrCelulas[i,j].EstaVazia() THEN RETURN False END END END RETURN True END FUNCTION ToString() IS string LOCAL sResultado IS string = "" i, j IS int FOR i = 0 TO 2 FOR j = 0 TO 2 sResultado += arrCelulas[i,j].GetValor() + " | " END sResultado = Left(sResultado, Length(sResultado)-3) + Charact(13) IF i < 2 THEN sResultado += "---------" + Charact(13) END RETURN sResultado END END ``` - **Encapsulamento**: A matriz é privada, acessada apenas por métodos. - **Responsabilidade Única**: Gerencia o tabuleiro e verifica o estado do jogo. - **Métodos**: `Jogar` para marcar uma jogada, `VerificarVitoria` para checar ganhador, `EstaCheio` para empate, `ToString` para exibição.
3. **Classe `Jogo`** Controla o fluxo do jogo e a interação com o usuário.
```wlanguage CLASS Jogo PRIVATE oTabuleiro IS Tabuleiro sJogadorAtual IS string = "X" PUBLIC PROCEDURE Iniciar() oTabuleiro = NEW Tabuleiro() Info("Bem-vindo ao Tic-Tac-Toe!") LOOP Info(oTabuleiro.ToString()) nLinha IS int = Val(Input("Jogador " + sJogadorAtual + " - Linha (0-2): ")) nColuna IS int = Val(Input("Jogador " + sJogadorAtual + " - Coluna (0-2): ")) IF oTabuleiro.Jogar(nLinha, nColuna, sJogadorAtual) THEN sVencedor IS string = oTabuleiro.VerificarVitoria() IF sVencedor <> "" THEN Info(oTabuleiro.ToString()) Info("Jogador " + sVencedor + " venceu!") BREAK END IF oTabuleiro.EstaCheio() THEN Info(oTabuleiro.ToString()) Info("Empate!") BREAK END sJogadorAtual = IIF(sJogadorAtual = "X", "O", "X") ELSE Info("Jogada inválida! Tente novamente.") END END END END ``` - **Separação de Camadas**: Interage com o usuário e delega a lógica ao `Tabuleiro`. - **Estado**: Alterna entre jogadores "X" e "O".
---
### Passo 2: Implementação no WinDev 1. Crie um projeto no WinDev. 2. Adicione as classes em um arquivo `.wls`. 3. No evento principal (ex.: botão "Jogar"), chame: ```wlanguage oJogo IS Jogo oJogo = NEW Jogo() oJogo.Iniciar() ```
4. **Interface Gráfica (opcional)**: - Use uma tabela 3x3 ou 9 botões no formulário. - Atualize a UI com `oTabuleiro.ToString()` ou crie um método para acessar a matriz diretamente. - Adicione eventos de clique para capturar as jogadas.
---
### Melhores Práticas Aplicadas - **SOLID**: - **S**: Cada classe tem uma única responsabilidade (`Celula` para estado, `Tabuleiro` para lógica, `Jogo` para fluxo). - **O**: Fácil de estender (ex.: para um tabuleiro 4x4, basta ajustar a matriz e a lógica de vitória). - **L**: Não aplicável diretamente (sem herança), mas respeitado em design. - **I**: Métodos públicos são específicos e mínimos. - **D**: Dependências são claras e injetadas (`Jogo` usa `Tabuleiro`).
- **Código Limpo**: - Nomes descritivos (`Jogar`, `VerificarVitoria`). - Funções curtas e focadas. - Validações para evitar erros (ex.: célula ocupada).
- **Reutilização**: - As classes podem ser adaptadas para outros jogos de tabuleiro.
---
### Passo 3: Melhorias Possíveis - **IA Oponente**: Adicione um método em `Jogo` para um jogador automático (ex.: usando Minimax). - **Reiniciar Jogo**: Inclua uma opção para reiniciar após o fim. - **Persistência**: Salve o estado com HFSQL do WinDev. - **UI Avançada**: Use imagens ou cores para "X" e "O" no WinDev.
Se quiser alguma dessas melhorias ou ajustes, é só pedir!
-- Adriano José Boller ______________________________________________ Consultor e Representante Oficial da PcSoft no Brasil +55 (41) 99949 1800 adrianoboller@gmail.com skype: adrianoboller http://wxinformatica.com.br/ |
| |
| |
| | | |
|
| | | | |
| | |
|