-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Commit do projeto foi feito para a branch master, mas a nomenclatura 'master' foi depreciada em favor da nomenclatura 'main'.
- Loading branch information
Showing
8 changed files
with
451 additions
and
0 deletions.
There are no files selected for viewing
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,148 @@ | ||
/* | ||
* Campo possui alguns eventos. Eventos de Campo sao identificados pelo enum CampoEvent. | ||
* Os observers de Campo implementam a Interface CampoObserver. | ||
* CampoObserver e uma FunctionalInterface BiConsumer. | ||
* Tabuleiro vai ser um Observer por controlar os campos | ||
*/ | ||
|
||
package com.yofiel.cm.modelo; | ||
|
||
import java.util.ArrayList; | ||
import java.util.HashSet; | ||
import java.util.List; | ||
import java.util.Set; | ||
|
||
public class Campo { | ||
|
||
// ATRIBUTOS | ||
private final int linha; | ||
private final int coluna; | ||
|
||
private boolean aberto; | ||
private boolean minado; | ||
private boolean marcado; | ||
|
||
private List<Campo> vizinhos = new ArrayList<>(); | ||
private Set<CampoObserver> observers = new HashSet<>(); | ||
|
||
// CONSTRUTOR | ||
Campo(int linha, int coluna) { | ||
this.linha = linha; | ||
this.coluna = coluna; | ||
} | ||
|
||
// SETTER E GETTERS | ||
void setAberto(boolean aberto) { | ||
this.aberto = aberto; | ||
|
||
if (aberto) { | ||
notificarObservers(CampoEvent.ABRIR); | ||
} | ||
} | ||
|
||
public boolean isMarcado() { | ||
return marcado; | ||
} | ||
|
||
public boolean isMinado() { | ||
return minado; | ||
} | ||
|
||
public boolean isAberto() { | ||
return aberto; | ||
} | ||
|
||
public int getLinha() { | ||
return linha; | ||
} | ||
|
||
public int getColuna() { | ||
return coluna; | ||
} | ||
|
||
// METODOS | ||
public void addObserver(CampoObserver observer) { | ||
observers.add(observer); | ||
} | ||
|
||
private void notificarObservers(CampoEvent evento) { | ||
observers.forEach(o -> o.eventoOcorreu(this, evento)); | ||
} | ||
|
||
boolean adicionarVizinho(Campo candidatoVizinho) { | ||
boolean linhaDiferente = linha != candidatoVizinho.linha; | ||
boolean colunaDiferente = coluna != candidatoVizinho.coluna; | ||
boolean diagonal = linhaDiferente && colunaDiferente; | ||
|
||
int deltaLinha = Math.abs(linha - candidatoVizinho.linha); | ||
int deltaColuna = Math.abs(coluna - candidatoVizinho.coluna); | ||
int deltaGeral = deltaColuna + deltaLinha; | ||
|
||
if (deltaGeral == 1 && !diagonal) { | ||
vizinhos.add(candidatoVizinho); | ||
return true; | ||
} else if (deltaGeral == 2 && diagonal) { | ||
vizinhos.add(candidatoVizinho); | ||
return true; | ||
} else { | ||
return false; | ||
} | ||
} | ||
|
||
public void alternarMarcacao() { | ||
if (!aberto) { | ||
marcado = !marcado; | ||
|
||
if (marcado) { | ||
notificarObservers(CampoEvent.MARCAR); | ||
} else { | ||
notificarObservers(CampoEvent.DESMARCAR); | ||
} | ||
} | ||
} | ||
|
||
public boolean abrir() { | ||
if (!aberto && !marcado) { | ||
if (minado) { | ||
notificarObservers(CampoEvent.EXPLODIR); | ||
return true; | ||
} | ||
|
||
setAberto(true); | ||
|
||
if (vizinhancaSegura()) { | ||
vizinhos.forEach(v -> v.abrir()); | ||
} | ||
|
||
return true; | ||
} else { | ||
return false; | ||
} | ||
} | ||
|
||
public boolean vizinhancaSegura() { | ||
return vizinhos.stream().noneMatch(v -> v.minado); | ||
} | ||
|
||
void minar() { | ||
minado = true; | ||
} | ||
|
||
boolean objetivoAlcancado() { | ||
boolean desvendado = !minado && aberto; | ||
boolean protegido = minado && marcado; | ||
return desvendado || protegido; | ||
} | ||
|
||
public int minasNaVizinhanca() { | ||
return (int) vizinhos.stream().filter(v -> v.minado).count(); | ||
} | ||
|
||
void reiniciar() { | ||
aberto = false; | ||
minado = false; | ||
marcado = false; | ||
notificarObservers(CampoEvent.REINICIAR); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
package com.yofiel.cm.modelo; | ||
|
||
public enum CampoEvent { | ||
|
||
ABRIR, MARCAR, DESMARCAR, EXPLODIR, REINICIAR | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package com.yofiel.cm.modelo; | ||
|
||
@FunctionalInterface | ||
public interface CampoObserver { | ||
// ESSA INTERFACE PODERIA SER SUBSTITUIDA PELA INTERFACE BICONSUMER DO PROPRIO JAVA | ||
public void eventoOcorreu(Campo campo, CampoEvent evento); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
package com.yofiel.cm.modelo; | ||
|
||
import java.util.ArrayList; | ||
import java.util.HashSet; | ||
import java.util.List; | ||
import java.util.Set; | ||
import java.util.function.Consumer; | ||
|
||
public class Tabuleiro implements CampoObserver { | ||
|
||
// ATRIBUTOS | ||
private final int linhas; | ||
private final int colunas; | ||
private final int minas; | ||
|
||
private final List<Campo> campos = new ArrayList<>(); | ||
private final Set<Consumer<Boolean>> observers = new HashSet<>(); | ||
|
||
// CONSTRUTOR | ||
public Tabuleiro(int linhas, int colunas, int minas) { | ||
this.linhas = linhas; | ||
this.colunas = colunas; | ||
this.minas = minas; | ||
|
||
gerarCampos(); | ||
associarVizinhos(); | ||
sortearMinas(); | ||
} | ||
|
||
// GETTERS | ||
public int getLinhas() { | ||
return linhas; | ||
} | ||
|
||
public int getColunas() { | ||
return colunas; | ||
} | ||
|
||
public int getMinas() { | ||
return minas; | ||
} | ||
|
||
public List<Campo> getCampos() { | ||
return campos; | ||
} | ||
|
||
// METODOS | ||
public void addObserver(Consumer<Boolean> observer) { | ||
observers.add(observer); | ||
} | ||
|
||
public void notificarObservers(boolean resultado) { | ||
observers.forEach(o -> o.accept(resultado)); | ||
} | ||
|
||
private void gerarCampos() { | ||
for (int linha = 0; linha < linhas; linha++) { | ||
for (int coluna = 0; coluna < colunas; coluna++) { | ||
Campo campo = new Campo(linha, coluna); | ||
campo.addObserver(this); | ||
campos.add(campo); | ||
} | ||
} | ||
} | ||
|
||
private void associarVizinhos() { | ||
for (Campo c1 : campos) { | ||
for (Campo c2 : campos) { | ||
c1.adicionarVizinho(c2); | ||
} | ||
} | ||
} | ||
|
||
private void sortearMinas() { | ||
long minasArmadas; | ||
|
||
do { | ||
int aleatorio = (int) (Math.random() * campos.size()); | ||
campos.get(aleatorio).minar(); | ||
minasArmadas = campos.stream().filter(c -> c.isMinado()).count(); | ||
} while (minasArmadas < minas); | ||
} | ||
|
||
public boolean objetivoAlcancado() { | ||
return campos.stream().allMatch(c -> c.objetivoAlcancado()); | ||
} | ||
|
||
public void reiniciar() { | ||
campos.stream().forEach(c -> c.reiniciar()); | ||
sortearMinas(); | ||
} | ||
|
||
private void mostrarMinas() { | ||
campos.stream().filter(c -> c.isMinado()).filter(c -> !c.isMarcado()).forEach(c -> c.setAberto(true)); | ||
} | ||
|
||
@Override | ||
public void eventoOcorreu(Campo campo, CampoEvent evento) { | ||
if (evento == CampoEvent.EXPLODIR) { | ||
mostrarMinas(); | ||
notificarObservers(false); | ||
} else if (objetivoAlcancado()) { | ||
notificarObservers(true); | ||
} | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
package com.yofiel.cm.visao; | ||
|
||
import java.awt.Color; | ||
import java.awt.event.MouseEvent; | ||
import java.awt.event.MouseListener; | ||
|
||
import javax.swing.BorderFactory; | ||
import javax.swing.JButton; | ||
|
||
import com.yofiel.cm.modelo.Campo; | ||
import com.yofiel.cm.modelo.CampoEvent; | ||
import com.yofiel.cm.modelo.CampoObserver; | ||
|
||
@SuppressWarnings("serial") | ||
public class BotaoCampo extends JButton implements CampoObserver, MouseListener { | ||
|
||
// ATRIBUTOS | ||
private static final Color BG_PADRAO = new Color(184, 184, 184); | ||
private static final Color BG_MARCAR = new Color(8, 179, 247); | ||
private static final Color BG_EXPLODIR = new Color(189, 66, 68); | ||
private static final Color TEXTO_VERDE = new Color(0, 100, 0); | ||
|
||
private Campo campo; | ||
|
||
// CONSTRUTOR | ||
public BotaoCampo(Campo campo) { | ||
this.campo = campo; | ||
setBackground(BG_PADRAO); | ||
setBorder(BorderFactory.createBevelBorder(0)); | ||
|
||
campo.addObserver(this); | ||
addMouseListener(this); | ||
} | ||
|
||
// METODOS | ||
@Override | ||
public void eventoOcorreu(Campo campo, CampoEvent evento) { | ||
switch (evento) { | ||
case ABRIR: | ||
aplicarEstiloAbrir(); | ||
break; | ||
case MARCAR: | ||
aplicarEstiloMarcar(); | ||
break; | ||
case EXPLODIR: | ||
aplicarEstiloExplodir(); | ||
break; | ||
default: | ||
aplicarEstiloPadrao(); | ||
} | ||
} | ||
|
||
private void aplicarEstiloPadrao() { | ||
setBackground(BG_PADRAO); | ||
setBorder(BorderFactory.createBevelBorder(0)); | ||
setText(""); | ||
} | ||
|
||
private void aplicarEstiloAbrir() { | ||
setBorder(BorderFactory.createLineBorder(Color.GRAY)); | ||
|
||
if (campo.isMinado()) { | ||
setBackground(BG_EXPLODIR); | ||
return; | ||
} | ||
|
||
switch (campo.minasNaVizinhanca()) { | ||
case 1: | ||
setForeground(TEXTO_VERDE); | ||
break; | ||
case 2: | ||
setForeground(Color.BLUE); | ||
break; | ||
case 3: | ||
setForeground(Color.YELLOW); | ||
break; | ||
case 4: | ||
case 5: | ||
case 6: | ||
setForeground(Color.RED); | ||
break; | ||
default: | ||
setForeground(Color.PINK); | ||
} | ||
|
||
String valor = !campo.vizinhancaSegura() ? campo.minasNaVizinhanca() + "" : ""; | ||
setText(valor); | ||
} | ||
|
||
private void aplicarEstiloMarcar() { | ||
setBackground(BG_MARCAR); | ||
setForeground(Color.BLACK); | ||
setText("M"); | ||
} | ||
|
||
private void aplicarEstiloExplodir() { | ||
setBackground(BG_EXPLODIR); | ||
setForeground(Color.WHITE); | ||
setText("*"); | ||
} | ||
|
||
// METODOS DA INTERFACE DOS EVENTOS DO MOUSE | ||
@Override | ||
public void mousePressed(MouseEvent e) { | ||
if (e.getButton() == 1) { | ||
campo.abrir(); | ||
} else { | ||
campo.alternarMarcacao(); | ||
} | ||
} | ||
|
||
public void mouseClicked(MouseEvent e) { | ||
} | ||
|
||
public void mouseReleased(MouseEvent e) { | ||
} | ||
|
||
public void mouseEntered(MouseEvent e) { | ||
} | ||
|
||
public void mouseExited(MouseEvent e) { | ||
} | ||
|
||
} |
Oops, something went wrong.