我正在开发一个使用网格系统的游戏(想想棋盘)。棋盘上的每个图块都有一个位置(行/列)。还有一个方向的概念(N,E,S,W,NE,SE,NW,SW)。
给定两个位置,我正在计算 3 个方向的东西:
- 方向(N、E、S、W、NE、SW、NW、SW、NONE 或 null。Null 是指瓦片没有在一个方向上完全对齐)。
- 大方向(如果不是特定方向之一,则属于 NE、SE、NW、SW 大方向)。
- 最近的方向(如果有平局,则为空)。
例如, (0, 0) -> (4, 3) 有:
- 零方向
- SE的总体方向
- SE最近的方向
和 (0, 0) -> (4, 1) 有:
- 零方向
- SE的总体方向
- S的最近方向
该代码有效,但非常难看。我确信必须有一种更简洁的算法来设置值,并且重复次数要少得多。关于减少重复代码的方法有什么想法吗?
public final class Dimension
{
private final int rowDistance;
private final int columnDistance;
private final Direction direction;
private final Direction generalDirection;
private final Direction closestDirection;
public Dimension(final Location locationA,
final Location locationB)
{
if(locationA == null)
{
throw new IllegalArgumentException("locationA cannot be null");
}
if(locationB == null)
{
throw new IllegalArgumentException("locationB cannot be null");
}
rowDistance = locationB.getRow() - locationA.getRow();
columnDistance = locationB.getColumn() - locationA.getColumn();
// not moving at all
if(rowDistance == 0 && columnDistance == 0)
{
direction = Direction.NONE;
generalDirection = Direction.NONE;
closestDirection = Direction.NONE;
}
else
{
final int absoluteDifference;
absoluteDifference = Math.abs(Math.abs(rowDistance) - Math.abs(columnDistance));
// North Westish
if(rowDistance <= 0 && columnDistance <= 0)
{
final int north;
final int west;
final int northWest;
if(absoluteDifference == 0)
{
direction = Direction.NORTH_WEST;
generalDirection = Direction.NORTH_WEST;
}
else if(rowDistance == 0)
{
direction = Direction.WEST;
generalDirection = Direction.WEST;
}
else if(columnDistance == 0)
{
direction = Direction.NORTH;
generalDirection = Direction.NORTH;
}
else
{
direction = null;
generalDirection = Direction.NORTH_WEST;
}
north = Math.abs(columnDistance);
west = Math.abs(rowDistance);
northWest = Math.abs(
Math.abs(Math.max(rowDistance, columnDistance)) -
Math.abs(Math.min(rowDistance, columnDistance)));
if(northWest < west && northWest < north)
{
closestDirection = Direction.NORTH_WEST;
}
else if(west < northWest && west < north)
{
closestDirection = Direction.WEST;
}
else if(north < northWest && north < west)
{
closestDirection = Direction.NORTH;
}
else
{
closestDirection = null;
}
}
// North Eastish
else if(rowDistance <= 0 && columnDistance >= 0)
{
final int north;
final int east;
final int northEast;
if(absoluteDifference == 0)
{
direction = Direction.NORTH_EAST;
generalDirection = Direction.NORTH_EAST;
}
else if(rowDistance == 0)
{
direction = Direction.EAST;
generalDirection = Direction.EAST;
}
else if(columnDistance == 0)
{
direction = Direction.NORTH;
generalDirection = Direction.NORTH;
}
else
{
direction = null;
generalDirection = Direction.NORTH_EAST;
}
north = Math.abs(columnDistance);
east = Math.abs(rowDistance);
northEast = Math.abs(
Math.abs(Math.max(rowDistance, columnDistance)) -
Math.abs(Math.min(rowDistance, columnDistance)));
if(northEast < east && northEast < north)
{
closestDirection = Direction.NORTH_EAST;
}
else if(east < northEast && east < north)
{
closestDirection = Direction.EAST;
}
else if(north < northEast && north < east)
{
closestDirection = Direction.NORTH;
}
else
{
closestDirection = null;
}
}
// South Westish
else if(rowDistance >= 0 && columnDistance <= 0)
{
final int south;
final int west;
final int southWest;
if(absoluteDifference == 0)
{
direction = Direction.SOUTH_WEST;
generalDirection = Direction.SOUTH_WEST;
}
else if(rowDistance == 0)
{
direction = Direction.WEST;
generalDirection = Direction.WEST;
}
else if(columnDistance == 0)
{
direction = Direction.SOUTH;
generalDirection = Direction.SOUTH;
}
else
{
direction = null;
generalDirection = Direction.SOUTH_WEST;
}
south = Math.abs(columnDistance);
west = Math.abs(rowDistance);
southWest = Math.abs(
Math.abs(Math.max(rowDistance, columnDistance)) -
Math.abs(Math.min(rowDistance, columnDistance)));
if(southWest < west && southWest < south)
{
closestDirection = Direction.SOUTH_WEST;
}
else if(west < southWest && west < south)
{
closestDirection = Direction.WEST;
}
else if(south < southWest && south < west)
{
closestDirection = Direction.SOUTH;
}
else
{
closestDirection = null;
}
}
// South Eastish
else
{
final int south;
final int east;
final int southEast;
if(absoluteDifference == 0)
{
direction = Direction.SOUTH_EAST;
generalDirection = Direction.SOUTH_EAST;
}
else if(rowDistance == 0)
{
direction = Direction.EAST;
generalDirection = Direction.EAST;
}
else if(columnDistance == 0)
{
direction = Direction.SOUTH;
generalDirection = Direction.SOUTH;
}
else
{
direction = null;
generalDirection = Direction.SOUTH_EAST;
}
south = Math.abs(columnDistance);
east = Math.abs(rowDistance);
southEast = Math.abs(
Math.abs(Math.max(rowDistance, columnDistance)) -
Math.abs(Math.min(rowDistance, columnDistance)));
if(southEast < east && southEast < south)
{
closestDirection = Direction.SOUTH_EAST;
}
else if(east < southEast && east < south)
{
closestDirection = Direction.EAST;
}
else if(south < southEast && south < east)
{
closestDirection = Direction.SOUTH;
}
else
{
closestDirection = null;
}
}
}
}
public int getRowDistance()
{
return (rowDistance);
}
public int getColumnDistance()
{
return (columnDistance);
}
public Direction getDirection()
{
return (direction);
}
public Direction getGeneralDirection()
{
return (generalDirection);
}
public Direction getClosestDirection()
{
return (closestDirection);
}
}