私はグリッド システム (チェス盤を考えてください) を使用するゲームに取り組んでいます。ボード上の各タイルには場所 (行/列) があります。方向 (N、E、S、W、NE、SE、NW、SW) の概念もあります。
2 つの場所を指定して、3 つの方向を計算しています。
- 方向 (N、E、S、W、NE、SW、NW、SW、NONE、または null。null は、タイルがいずれかの方向に正確に整列していない場合)。
- 一般的な方向 (特定の方向のいずれでもない場合は、NE、SE、NW、SW の一般的な方向に分類されます)。
- 最も近い方向 (同点の場合は null)。
たとえば、(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);
}
}