PC SOFT

FOROS PROFESIONALES
WINDEVWEBDEV y WINDEV Mobile

Inicio → WINDEV 25 → Jogo da Memória (Memory Game) em WLanguage, utilizando Orientação a Objetos (OOP)
Jogo da Memória (Memory Game) em WLanguage, utilizando Orientação a Objetos (OOP)
Iniciado por Boller, 17,mar. 2025 16:59 - No hay respuesta
Miembro registrado
4.520 mensajes
Publicado el 17,marzo 2025 - 16:59
Boa tarde,

Vou criar uma implementação do Jogo da Memória (Memory Game) em WLanguage, utilizando Orientação a Objetos (OOP) e aplicando as melhores práticas, como encapsulamento, responsabilidade única (SOLID), modularidade e código limpo. O jogo consistirá em um tabuleiro com cartas viradas para baixo, que o jogador deve virar duas por vez para encontrar pares iguais. Usaremos um tabuleiro 4x4 (16 cartas, 8 pares) para exemplificar.

---

### Estrutura do Projeto
Dividiremos o código em classes com responsabilidades claras:
- **`Carta`**: Representa uma carta no jogo.
- **`Tabuleiro`**: Gerencia o estado do jogo, incluindo as cartas e a lógica de pares.
- **`Jogo`**: Controla a interação com o usuário e o fluxo do jogo.

---

### Passo 1: Código das Classes

1. **Classe `Carta`**
Representa uma carta com um valor (ex.: número ou símbolo) e estado (virada ou não).

```wlanguage
CLASS Carta
PRIVATE
sValor IS string // Valor da carta (ex.: "A", "1", etc.)
bVirada IS boolean // Estado: virada (True) ou não (False)
bCombinada IS boolean // Se já foi combinada com seu par
PUBLIC
PROCEDURE Construtor(sNovoValor IS string)
sValor = sNovoValor
bVirada = False
bCombinada = False
END
FUNCTION GetValor() IS string
RETURN sValor
END
FUNCTION EstaVirada() IS boolean
RETURN bVirada
END
FUNCTION EstaCombinada() IS boolean
RETURN bCombinada
END
PROCEDURE Virar()
IF NOT bCombinada THEN
bVirada = NOT bVirada
END
END
PROCEDURE MarcarComoCombinada()
bCombinada = True
bVirada = True
END
FUNCTION ToString() IS string
IF bCombinada THEN RETURN sValor
IF bVirada THEN RETURN sValor
RETURN "?"
END
END
```
- **Encapsulamento**: Estado interno privado, manipulado por métodos.
- **Responsabilidade**: Gerencia apenas os dados e o estado de uma carta.

2. **Classe `Tabuleiro`**
Gerencia as cartas, embaralha e verifica pares.

```wlanguage
CLASS Tabuleiro
PRIVATE
arrCartas IS array of Carta[4,4] // Matriz 4x4
nParesEncontrados IS int // Contador de pares
PUBLIC
PROCEDURE Construtor()
LOCAL
arrValores IS array of string
i, j, nIdx IS int
// Define 8 pares (ex.: "A" a "H")
arrValores = ["A","A","B","B","C","C","D","D","E","E","F","F","G","G","H","H"]
// Embaralha os valores
ArrayShuffle(arrValores)
// Preenche o tabuleiro
nIdx = 0
FOR i = 0 TO 3
FOR j = 0 TO 3
arrCartas[i,j] = NEW Carta(arrValores[nIdx])
nIdx += 1
END
END
nParesEncontrados = 0
END
FUNCTION VirarCarta(nLinha IS int, nColuna IS int) IS boolean
IF nLinha >= 0 AND nLinha <= 3 AND nColuna >= 0 AND nColuna <= 3 THEN
IF NOT arrCartas[nLinha,nColuna].EstaCombinada() AND NOT arrCartas[nLinha,nColuna].EstaVirada() THEN
arrCartas[nLinha,nColuna].Virar()
RETURN True
END
END
RETURN False
END
FUNCTION VerificarPar(nLinha1 IS int, nColuna1 IS int, nLinha2 IS int, nColuna2 IS int) IS boolean
IF arrCartas[nLinha1,nColuna1].GetValor() = arrCartas[nLinha2,nColuna2].GetValor() THEN
arrCartas[nLinha1,nColuna1].MarcarComoCombinada()
arrCartas[nLinha2,nColuna2].MarcarComoCombinada()
nParesEncontrados += 1
RETURN True
ELSE
arrCartas[nLinha1,nColuna1].Virar() // Desvira
arrCartas[nLinha2,nColuna2].Virar() // Desvira
RETURN False
END
END
FUNCTION EstaCompleto() IS boolean
RETURN nParesEncontrados = 8 // 8 pares no total
END
FUNCTION ToString() IS string
LOCAL
sResultado IS string = ""
i, j IS int
FOR i = 0 TO 3
FOR j = 0 TO 3
sResultado += arrCartas[i,j].ToString() + " "
END
sResultado += Charact(13) // Nova linha
END
RETURN sResultado
END
END
```
- **Encapsulamento**: A matriz e o contador são privados.
- **Responsabilidade Única**: Gerencia o tabuleiro e a lógica de pares.
- **Métodos**: `VirarCarta` para virar, `VerificarPar` para checar e atualizar, `EstaCompleto` para vitória.

3. **Classe `Jogo`**
Controla o fluxo e a interação com o usuário.

```wlanguage
CLASS Jogo
PRIVATE
oTabuleiro IS Tabuleiro
nJogadas IS int
PUBLIC
PROCEDURE Iniciar()
oTabuleiro = NEW Tabuleiro()
nJogadas = 0
Info("Bem-vindo ao Jogo da Memória 4x4!")
LOOP
Info(oTabuleiro.ToString())
// Primeira carta
nLinha1 IS int = Val(Input("Linha da 1ª carta (0-3): "))
nCol1 IS int = Val(Input("Coluna da 1ª carta (0-3): "))
IF NOT oTabuleiro.VirarCarta(nLinha1, nCol1) THEN
Info("Posição inválida ou já virada! Tente novamente.")
CONTINUE
END
Info(oTabuleiro.ToString())
// Segunda carta
nLinha2 IS int = Val(Input("Linha da 2ª carta (0-3): "))
nCol2 IS int = Val(Input("Coluna da 2ª carta (0-3): "))
IF NOT oTabuleiro.VirarCarta(nLinha2, nCol2) THEN
Info("Posição inválida ou já virada! Tente novamente.")
oTabuleiro.VirarCarta(nLinha1, nCol1) // Desvira a primeira
CONTINUE
END
Info(oTabuleiro.ToString())
// Verifica par
IF oTabuleiro.VerificarPar(nLinha1, nCol1, nLinha2, nCol2) THEN
Info("Par encontrado!")
ELSE
Info("Não é um par. Cartas serão desviradas.")
END
nJogadas += 1
IF oTabuleiro.EstaCompleto() THEN
Info(oTabuleiro.ToString())
Info("Parabéns! Você venceu em " + nJogadas + " jogadas!")
BREAK
END
END
END
END
```
- **Separação de Camadas**: Cuida da interação e delega lógica ao `Tabuleiro`.
- **Controle**: Gerencia as jogadas e exibe mensagens.

---

### 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 "Iniciar"), chame:
```wlanguage
oJogo IS Jogo
oJogo = NEW Jogo()
oJogo.Iniciar()
```

4. **Interface Gráfica (opcional)**:
- Use uma tabela 4x4 ou 16 botões no formulário.
- Atualize a UI com `oTabuleiro.ToString()` ou acesse a matriz diretamente.
- Adicione eventos de clique para virar cartas.

---

### Melhores Práticas Aplicadas
- **SOLID**:
- **S**: Cada classe tem uma única responsabilidade (`Carta` para estado, `Tabuleiro` para lógica, `Jogo` para fluxo).
- **O**: Fácil de estender (ex.: mudar para 6x6 ajustando o construtor e os pares).
- **L**: Não há herança, mas o design é coeso.
- **I**: Métodos públicos são específicos.
- **D**: Dependências são injetadas (`Jogo` usa `Tabuleiro`).

- **Código Limpo**:
- Nomes descritivos (`VirarCarta`, `VerificarPar`).
- Funções pequenas e claras.
- Validações para evitar erros (ex.: carta já virada).

- **Reutilização**:
- Classes podem ser adaptadas para outros tamanhos ou temas (ex.: imagens).

---

### Passo 3: Melhorias Possíveis
- **Temporizador**: Adicione um contador de tempo em `Jogo`.
- **Pontuação**: Considere penalidades por jogadas erradas.
- **UI Avançada**: Use imagens no WinDev para as cartas (ex.: ícones ou fotos).
- **Persistência**: Salve o progresso com HFSQL.

Se precisar de detalhes ou melhorias específicas, é só avisar!

--
Adriano José Boller
______________________________________________
Consultor e Representante Oficial da
PcSoft no Brasil
+55 (41) 99949 1800
adrianoboller@gmail.com
skype: adrianoboller
http://wxinformatica.com.br/