What is a good way to implement calculations for extended classes?



I have the following classes:

public class Node {
    private int x;
    private int y;

}
public abstract class Map {
    protected Node[][] grid;
    
    public abstract Set<Node> findNeighbours(Node node);
}
public class SquareMap extends Map {
    private static final int VERTICAL_COST= 10;
    private static final int HORIZONTAL_COST= 10;
    private static final int DIAGONAL_COST = 14;

    @Override
    public Set<Node> findNeighbours(Node node) {
        //return the 8 adjacent nodes
    }
}
public class HexMap extends Map {
    private static final int MOVE_COST = 10;

    @Override
    public Set<Node> findNeighbours(Node node) {
        //return the 6 adjacent nodes
    }
}

I would like to create a method like

public int calculateMoveCost(Node current, Node target, <whatever else is needed>) {}

Where I only pass in the nodes, and the logic in either the method, or the nodes, or the map recognizes what kind of map I’m using. My current solution looks like this:

    private int calculateMoveCost(Node current, Node target, Map map) {
        int cost;
        if(isHexMap(map)) {
            cost = map.getMoveCost();
        } else {
            if(isSquareMap(map)) {
                if(verticalNeighbours(current, target)) {
                    cost = map.getVerticalMoveCost();
                } else {
                    cost = map.getHorizontalMoveCost();
                }
            }
        }
        return cost;
    }

When I look at this code, I think there has to be a better way to implement this. Could you recommend a nice object oriented way of implementing this? I can create any reference in any object, the goal is to have a nice solution. Thanks!

Answer

I do think there is a right answer for this, just have an abstract getMoveCost method on Map and implement it in each subclass. Then you can just call map.getMoveCost(from, to).

public abstract class Map {
    protected Node[][] grid;
    
    public abstract int getMoveCost(Node current, Node target);
    public abstract Set<Node> findNeighbours(Node node);
}

public class SquareMap extends Map {
    private static final int VERTICAL_COST= 10;
    private static final int HORIZONTAL_COST= 10;
    private static final int DIAGONAL_COST = 14;

    @Override
    public Set<Node> findNeighbours(Node node) {
        //return the 8 adjacent nodes
    }

    @Override
    public int getMoveCost(Node current, Node target) {
        if(verticalNeighbours(current, target)) {            
            cost = getVerticalMoveCost();
        } else {
            cost = getHorizontalMoveCost();
        }
    }
}


Source: stackoverflow