Справка по домашнему заданию, абстрактные / интерфейсные классы

#java #interface #abstract #river-crossing-puzzle

#java #интерфейс #аннотация #переправа через реку-головоломка

Вопрос:

Я новичок в работе с Java, и курс, который я прохожу, показывает мне некоторый код, но когда я пытаюсь его запустить. Он возвращает исключение с нулевым указателем из-за того, что родительский элемент никогда не был установлен.

Итак, как мне передать родительский класс в абстрактном классе? Это основано на поиске AI! Спасибо!!

Вот код:

Это основано на проблеме с капустой farmer wolf goat.

AbstractState:

 package hw1;

public abstract class AbstractState implements State
{
    public State parent = null;
    private double distance = 0;

    public AbstractState(){}
    public AbstractState(State Parent)
    {
        this.parent = parent;
        this.distance = parent.getDistance()  1;
    }

    public State getParent()
    {
        return parent;
    }

    public double getDistance()
    {
        return distance;
    }

}
  

Состояние

 package hw1;
import java.util.Set;


public interface State 
{
    public Iterable<State> getPossibleMoves();
    public boolean isSolution();
    public double getHeuristic();
    public double getDistance();
    public State getParent();
}
  

FarmerWolfGoatCabbage:

 package hw1;
import java.util.HashSet;
import java.util.Set;


public class FarmerWolfGoatState extends AbstractState 
{
    enum Side
    {
        EAST 
        {
            public Side getOpposite()
            {
                return WEST;
            }
        },
        WEST
        {
            public Side getOpposite()
            {
                return EAST;
            }
        };

        abstract public Side getOpposite();
    }

    private Side farmer = Side.EAST;
    private Side wolf = Side.EAST;
    private Side goat = Side.EAST;
    private Side cabbage = Side.EAST;

    public FarmerWolfGoatState()
    {}

    public FarmerWolfGoatState(FarmerWolfGoatState parent, Side farmer, Side wolf, Side goat, Side Cabbage)
    {
        super(parent);
        this.farmer = farmer;
        this.wolf = wolf;
        this.goat = goat;
        this.cabbage = cabbage;
    }

    @Override
    public Iterable<State> getPossibleMoves() {
        Set<State> moves = new HashSet<State>();

        if(farmer == wolf)
            new FarmerWolfGoatState(this,
                    farmer.getOpposite()
                    ,wolf.getOpposite()
                    ,goat,cabbage).addIfSafe(moves);

        if(farmer == goat)
            new FarmerWolfGoatState(this,
                    farmer.getOpposite()
                    ,wolf
                    ,goat.getOpposite(),cabbage).addIfSafe(moves);

        if(farmer == cabbage)
            new FarmerWolfGoatState(this,
                    farmer.getOpposite()
                    ,wolf
                    ,goat,cabbage.getOpposite()).addIfSafe(moves);

        new FarmerWolfGoatState(this, farmer.getOpposite(), wolf, goat, cabbage).addIfSafe(moves);

        return moves;

    }

    @Override
    public boolean isSolution() {
        //returns true if all of the them are on the west side and not the east.
        return farmer == Side.WEST amp;amp; wolf == Side.WEST amp;amp; goat==Side.WEST amp;amp; cabbage == Side.WEST;

    }

    @Override
    public double getHeuristic() {
        // TODO Auto-generated method stub
        return 0;
    }

    public final void addIfSafe(Set<State> moves)
    {
        boolean unsafe = (farmer!= wolf amp;amp; farmer != goat) || (farmer != goat amp;amp; farmer != cabbage);

        if(!unsafe)
            moves.add(this);
    }

    public boolean equals(Object o)
    {
        if(o == null || !(o instanceof FarmerWolfGoatState))
            return false;
        FarmerWolfGoatState fwgs = (FarmerWolfGoatState)o;

        return farmer == fwgs.farmer amp;amp;
                wolf == fwgs.wolf amp;amp;
                cabbage == fwgs.cabbage amp;amp;
                goat == fwgs.goat;
    }

    public int hashCode()
    {
        return(farmer == Side.EAST ? 1 : 0)  
                (wolf == Side.EAST ? 2 : 0)  
                (cabbage == Side.EAST ? 4: 0) 
                (goat == Side.EAST ? 8 : 0);
    }

}
  

Главная попытка решить..

 package hw1;

import hw1.FarmerWolfGoatState.Side;



public class Homework1 {

    /**
     * @param args
     */
    public static void main(String[] args) 
    {
        FarmerWolfGoatState parentState = new FarmerWolfGoatState();
        FarmerWolfGoatState nextState = new FarmerWolfGoatState(parentState,Side.EAST,Side.EAST,Side.EAST,Side.WEST);

        while(!nextState.isSolution())
        {
            nextState.getPossibleMoves();
        }

    }


}
  

Трассировка стека:

 Exception in thread "main" java.lang.NullPointerException
    at hw1.AbstractState.<init>(AbstractState.java:12)
    at hw1.FarmerWolfGoatState.<init>(FarmerWolfGoatState.java:38)
    at hw1.Homework1.main(Homework1.java:15)
  

Мне также дали решатель, должен ли я его использовать?

 here it is.
package hw1;
import java.util.Stack;


public class DepthFirstSolver extends AbstractSolver
{
    private Stack<State> stack = new Stack<State>();

    @Override
    protected void addState(State s)
    {
        if(!stack.contains(s))
        {
            stack.push(s);
        }
    }

    @Override
    protected boolean hasElements()
    {
        return !stack.empty();
    }

    @Override
    protected State nextState()
    {
        return stack.pop();
    }
    @Override
    protected void clearOpen()
    {
        stack.clear();
    }

}


package hw1;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;




public abstract class AbstractSolver implements Solver 
{
    private Set<State> closed= new HashSet<State>();

    public List<State> solve(State initialState)
    {
        closed.clear();
        clearOpen();
        while(hasElements())
        {
            State s = nextState();
            if(s.isSolution())
                return findPath(s);
            closed.add(s);
            Iterable<State> moves = s.getPossibleMoves();
            for(State move : moves)
                if(!closed.contains(move))
                        addState(move);
        }
        return null;

    }
    public int getVisitedStateCount()
    {
        return closed.size();
    }

    private List<State> findPath(State solution)
    {
        LinkedList<State> path = new LinkedList<State>();
        while(solution!=null)
        {
            path.addFirst(solution);
            solution = solution.getParent();

        }
        return path;
    }

    protected abstract boolean hasElements();
    protected abstract State nextState();
    protected abstract void addState(State s);
    protected abstract void clearOpen();

}
  

Комментарии:

1. Для меня выглядит хорошо. Опубликовать сообщение об ошибке исключения и трассировку стека.

2. @DarylTeo Опубликована трассировка стека! Большое вам спасибо

Ответ №1:

Похоже на проблему с прописными / строчными буквами, вам нужно изменить конструктор AbstractState на

 public AbstractState(State parent)
  

вместо

 public AbstractState(State Parent)
  

В строке this.distance = parent.getDistance() 1; ваш конструктор использует неинициализированную переменную экземпляра name parent вместо входного параметра name Parent .

Комментарии:

1. ого. Спасибо, Калеб! Я писал это некоторое время, но я только что заметил это. ха-ха! Спасибо, похоже на глупую ошибку!!

2. о, еще один вопрос, как следует использовать решатель? Можете ли вы привести мне пример?