#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. о, еще один вопрос, как следует использовать решатель? Можете ли вы привести мне пример?