GUJ Discussões   :   últimos tópicos   |   categorias   |   GUJ Respostas

Não estou entendendo a interação entre esses dois metodos

0

Boa noite, possuo um algortimo de campo em minado e o meu professor passou os seguintes metodos explicando em video, porem a explicação não foi clara quanto a interação entre os dois metodos. Alguem poderia me ajudar a entender passo a passo, e como esse lambda esta funcionando na interação?

o metodo que vai ser chamado em outro metodo é esse:

boolean vizinhancaSegura() {
    return vizinhos.stream().noneMatch(v -> v.minado);
}

o metodo que vai chamar ele é esse:

boolean abrir() {

    if (!aberto && !marcado) {
        aberto = true;

        if (minado) {
            throw new ExplosaoException();
        }
        if (vizinhancaSegura()) {
            vizinhos.forEach(v -> v.abrir());
        }
        return true;
    } else {
        return false;
    }
}

a variavel “vizinhos” é uma lista do mesmo tipo da classe

private List<Campo> vizinhos = new ArrayList<>();

Não entendi como o noneMatch vai ajudar, e o que ele esta colocando ou verificando, e como essa interação entre os dois metodos funciona, passo a passo. só possuo essa classe, ou seja, ta tudo ali.

Caso tenha ficado confuso a explicação por conta da ocultação de alguma parte do codigo, segue o codigo completo:

import java.util.ArrayList;
import java.util.List;

import excecao.ExplosaoException;

public class Campo {

    private final int linha;
    private final int coluna;

    private boolean aberto = false;
    private boolean minado = false;
    private boolean marcado = false;

    private List<Campo> vizinhos = new ArrayList<>();

    Campo(int linha, int coluna) {
        this.linha = linha;
        this.coluna = coluna;
    }
    
    void minar() {
            minado = true;
    }

    boolean adicionarVizinho(Campo vizinho) {
        // verificando se é diferente do bloco atual
        boolean linhaDiferente = linha != vizinho.linha;
        boolean colunaDiferente = coluna != vizinho.coluna;
        // só vai marcar true se os dois forem true
        boolean diagonal = linhaDiferente && colunaDiferente;

        // somando
        int deltaLinha = Math.abs(this.linha - vizinho.linha);
        int deltaColuna = Math.abs(this.coluna - vizinho.coluna);
        int deltaGeral = deltaColuna + deltaLinha;

        if (deltaGeral == 1 && !diagonal) {
            vizinhos.add(vizinho);
            return true;
        } else if (deltaGeral == 2 && diagonal) {
            return true;
        } else {
            return false;
        }
    }

    void alternarMarcacao() {
        if (!aberto) {
            // se estiver marcado fica false e vice versa
            marcado = !marcado;
        }
    }

    boolean abrir() {

        if (!aberto && !marcado) {
            aberto = true;

            if (minado) {
                throw new ExplosaoException();
            }
            if (vizinhancaSegura()) {
                // vai chamar a si mesmo até não ter aonde abrir
                vizinhos.forEach(v -> v.abrir());
            }
            // o campo foi aberto nessa execução, por isso o true
            return true;
        } else {
            return false;
        }
    }

    boolean vizinhancaSegura() {
        // se der falso, quer dizer que um dos vizinhos esta minado e a vizinhança não é
        // segura
        return vizinhos.stream().noneMatch(v -> v.minado);
    }
    
    
    //como não gera nenhum efeito colateral, pode ser publico
    public boolean isMarcado() {
        return marcado;
    }
    
    public boolean isAberto() {
        return this.aberto;
    }
}

Essa linha: vizinhos.stream().noneMatch(v -> v.minado); é equivalente à:

vizinhos.stream().noneMatch(v -> v.minado == true);

Ou seja, vai verificar, para cada vizinho, se o atributo minado é verdadeiro. Se nenhum der verdadeiro, o método noneMatch (do inglês: nenhuma correspondência) retornará false, o que significa que nenhum vizinho está minado.

O lambda só deixa o código mais curto para não ter que ficar fazendo laço para esse tipo de verificação.

1 Curtida

Mas como que os dois metodos se ligam?
o metodo abrir chama o VizinhancaSegura CASO ele seja true, mas ele só retorna falso

Tem que ser adicionado um vizinho no método adicionarVizinho onde esse vizinho seja minado (método: minar).

//