PC SOFT

FOROS PROFESIONALES
WINDEVWEBDEV y WINDEV Mobile

Inicio → WINDEV 25 → Jogo Puzzle feito com WLanguage e oop
Jogo Puzzle feito com WLanguage e oop
Iniciado por Boller, 17,mar. 2025 16:52 - No hay respuesta
Miembro registrado
4.520 mensajes
Publicado el 17,marzo 2025 - 16:52
Boa tarde,

Vou te guiar na implementação de um jogo de Puzzle (como o clássico "Quebra-Cabeça Deslizante" ou "Sliding Puzzle") em WLanguage, utilizando Orientação a Objetos (OOP) e as melhores práticas. Como WLanguage é a linguagem da plataforma WinDev, ela suporta OOP com classes, herança, encapsulamento e polimorfismo, mas tem suas particularidades. O objetivo é criar um código modular, reutilizável e de fácil manutenção.

### Descrição do Jogo
Vamos criar um quebra-cabeça 3x3 (9 peças, sendo uma vazia) onde o jogador move as peças para organizá-las em ordem numérica. Usaremos:
- **OOP**: Classes para representar o tabuleiro, as peças e a lógica do jogo.
- **Boas Práticas**: Encapsulamento, responsabilidade única (SOLID), e código limpo.

---

### Passo 1: Estrutura do Projeto
1. **Classe `Peca`**
Representa cada peça do quebra-cabeça.

```wlanguage
CLASS Peca
PRIVATE
nNumero IS int // Número da peça (1 a 8, 0 para vazio)
nLinha IS int // Posição atual (linha)
nColuna IS int // Posição atual (coluna)
PUBLIC
PROCEDURE Construtor(nNum IS int, nLin IS int, nCol IS int)
nNumero = nNum
nLinha = nLin
nColuna = nCol
END
FUNCTION GetNumero() IS int
RETURN nNumero
END
FUNCTION GetPosicao() IS string
RETURN "(" + nLinha + "," + nColuna + ")"
END
PROCEDURE SetPosicao(nLin IS int, nCol IS int)
nLinha = nLin
nColuna = nCol
END
END
```
- **Encapsulamento**: Variáveis privadas, acessadas por métodos públicos.
- **Responsabilidade**: A classe só gerencia os dados da peça.

2. **Classe `Tabuleiro`**
Gerencia o estado do jogo e a lógica de movimentação.

```wlanguage
CLASS Tabuleiro
PRIVATE
arrPecas IS array of Peca[3,3] // Matriz 3x3 de peças
nVazioLinha IS int // Posição do espaço vazio (linha)
nVazioColuna IS int // Posição do espaço vazio (coluna)
PUBLIC
PROCEDURE Construtor()
LOCAL
nContador IS int = 1
i, j IS int
FOR i = 0 TO 2
FOR j = 0 TO 2
IF nContador < 9 THEN
arrPecas[i,j] = NEW Peca(nContador, i, j)
nContador += 1
ELSE
arrPecas[i,j] = NEW Peca(0, i, j) // Peça vazia
nVazioLinha = i
nVazioColuna = j
END
END
END
END
FUNCTION Mover(nLin IS int, nCol IS int) IS boolean
// Verifica se o movimento é válido (adjacente ao vazio)
IF Abs(nLin - nVazioLinha) + Abs(nCol - nVazioColuna) = 1 THEN
// Troca a peça com o vazio
arrPecas[nVazioLinha, nVazioColuna].SetPosicao(nLin, nCol)
arrPecas[nLin, nCol].SetPosicao(nVazioLinha, nVazioColuna)
// Atualiza a posição do vazio
Swap(arrPecas[nVazioLinha, nVazioColuna], arrPecas[nLin, nCol])
nVazioLinha = nLin
nVazioColuna = nCol
RETURN True
END
RETURN False
END
FUNCTION EstaResolvido() IS boolean
LOCAL
nEsperado IS int = 1
i, j IS int
FOR i = 0 TO 2
FOR j = 0 TO 2
IF i = 2 AND j = 2 THEN
RETURN arrPecas[i,j].GetNumero() = 0
END
IF arrPecas[i,j].GetNumero() <> nEsperado THEN
RETURN False
END
nEsperado += 1
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 += arrPecas[i,j].GetNumero() + " "
END
sResultado += Charact(13) // Nova linha
END
RETURN sResultado
END
END
```

- **Encapsulamento**: A matriz e a posição do vazio são privadas.
- **Responsabilidade Única**: O tabuleiro só gerencia o estado e a lógica do jogo.
- **Métodos**: `Mover` para trocar peças, `EstaResolvido` para verificar vitória, `ToString` para exibir o tabuleiro.

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

```wlanguage
CLASS Jogo
PRIVATE
oTabuleiro IS Tabuleiro
PUBLIC
PROCEDURE Iniciar()
oTabuleiro = NEW Tabuleiro()
Info("Bem-vindo ao Puzzle 3x3!")
LOOP
Info(oTabuleiro.ToString())
nLinha IS int = Val(Input("Linha da peça a mover (0-2): "))
nColuna IS int = Val(Input("Coluna da peça a mover (0-2): "))
IF oTabuleiro.Mover(nLinha, nColuna) THEN
IF oTabuleiro.EstaResolvido() THEN
Info("Parabéns! Você venceu!")
BREAK
END
ELSE
Info("Movimento inválido!")
END
END
END
END
```

- **Separação de Camadas**: A classe `Jogo` cuida da interface e da lógica de alto nível, delegando o trabalho ao `Tabuleiro`.

---

### Passo 2: Implementação no WinDev
1. Crie um novo projeto no WinDev.
2. Adicione as classes acima em um arquivo de código (`.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 3x3 no formulário WinDev.
- Atualize os valores da tabela com `oTabuleiro.ToString()` ou crie um método em `Tabuleiro` para retornar a matriz diretamente.
- Adicione botões ou eventos de clique para capturar os movimentos.

---

### Melhores Práticas Aplicadas
- **SOLID**:
- **S**: Cada classe tem uma única responsabilidade (`Peca` para dados, `Tabuleiro` para lógica, `Jogo` para interação).
- **O**: O código é aberto para extensão (ex.: adicionar um tabuleiro 4x4 só exige ajustar o construtor).
- **L**: Não há herança aqui, mas se fosse usada, respeitaria a substituição correta.
- **I**: Interfaces não são nativas em WLanguage, mas os métodos públicos são mínimos e específicos.
- **D**: Dependências são injetadas (ex.: `Jogo` usa `Tabuleiro`).

- **Código Limpo**:
- Nomes descritivos (`Mover`, `EstaResolvido`).
- Funções pequenas e focadas.
- Comentários onde necessário.

- **Reutilização**:
- As classes podem ser usadas em outros projetos ou expandidas (ex.: para um puzzle maior ou com imagens).

---

### Passo 3: Melhorias Possíveis
- **Embaralhar o Tabuleiro**: Adicione um método em `Tabuleiro` para embaralhar as peças no início, fazendo movimentos válidos aleatórios.
- **Persistência**: Use o HFSQL do WinDev para salvar o estado do jogo.
- **UI Avançada**: Integre com controles gráficos do WinDev para uma experiência visual.

Se precisar de mais detalhes ou ajustes (como embaralhar ou UI), é 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/