0

私はグリッド システム (チェス盤を考えてください) を使用するゲームに取り組んでいます。ボード上の各タイルには場所 (行/列) があります。方向 (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);
    }
}
4

1 に答える 1

1

私はあなたが持っているのと同じように距離を計算し、直交距離を Math.Atan2 に渡して、(int)Math.Round(H * 4 / Math.PI) を範囲 0 にスケーリングできる見出し H を計算します。 7 は、N からコンパス ポイントを時計回りにカウントするハッシュであり、時計回りに列挙すると仮定して列挙型に直接キャストできます。

于 2012-10-31T05:09:53.103 に答える