Java 问题 RobotSim 使用枚举命令、某些字符和约束在 2d 字符串映射中移动

问题描述 投票:0回答:1

我正在开发一个基本机器人应用程序的项目。我正在使用一些类和枚举,并且要使用我的枚举来移动,在这里我有点困惑。 所以我现在正在研究我的主要课程 - Robo。这是 Robo 的 uml/我正在做的事情仅供参考:

-currenLocate : Point
- directionFacing : FacingDirection
-map : FloorMap
- Carryingthing : boolean
-successfullyDropped : boolean

+Robo(map : FloorMap)
+Robo(map : FloorMap,currentLocatiom.  
: Point)
+move(command : RoboCommand) : void
+iscarryingThing() : boolean
+isSuccessfullyDropped() :boolean.

好的,所以我正在研究我的 move(),我需要考虑我的枚举,FacingDirection(所有 4 个方向),MapObject(要拾取的项目),然后考虑我的运动枚举(向前,向左,向右,拾取)并下降)。然后是我的两个布尔值。

所以我知道我需要面向方向并在通过枚举输入命令时考虑到这一点,但是您认为我最好的行动方案是什么?我在想 else 和 else if 和一些 &&,也许还有一个数组,但现在我不完全确定。我必须执行forwardfromup、forwardfromdown等操作。如果需要,我可以提供更多信息,但如果我可以帮助的话,我不想让这篇文章陷入太多困境。 =D。感谢您的宝贵时间,并提前感谢您提供任何帮助/提示。

java robotics
1个回答
1
投票

您没有提供完整的信息,因此有一些假设:

  • FloorMap 表示具有 x,y 坐标(从 0 开始)的点的 2D 区域
  • 一个点代表单个 x,y 坐标和一个可选的 MapObject
  • 面向方向为上/下(y 轴)和左/右(x 轴)
  • 机器人将始终位于地板上面向某个方向的点
  • RoboCommand 可以是:前进、左转、右转、拾取、放下

例如,Robo 可以位于 FloorMap 中的点 (4,2) 处,面朝上:

........
....a...
........
...^....
........

(5,4) 处的点持有一个 MapObject (a)

要获取MapObject,Robo需要执行以下命令:

forward, forward, right, forward, pick up

上下文就这么多。

要开始实现这一点,您需要创建域类:

  • 楼层地图、点、地图对象
  • 面向方向
  • 机器人指挥

您可以使用枚举来实现遵循 命令模式的命令(尽管我更喜欢为此使用单独的类)。

public enum RoboCommand {

    FORWARD() {
        void execute(Robo robo) {    
            // determine the new coordinates by adding the appropriate deltas
            long x = robo.getCurrentLocation().getX() + robo.getFacingDirection().deltaX();
            long y = robo.getCurrentLocation().getY() + robo.getFacingDirection().deltaY();
            // get (or create) the matching Point from the floorMap
            robo.getFloorMap().getPoint(x, y);
            // move Robo to the new point
            robo.setCurrentLocation(point);
        }
    }, RIGHT {
        void execute(Robo robo) {
            //use the left/right logic in FacingDirection
            FacingDirection direction = robo.getFacingDirection().right();
            // face Robo in the new direction
            robo.setFacingDirection(direction);
        }
    }, LEFT {
        void execute(Robo robo) {
            robo.setFacingDirection(robo.getFacingDirection().left());
        }
    }, PICK_UP {
        void execute(Robo robo) {
            // get the optional item from the current Point
            robo.getCurrentLocation().getItem()
                .ifPresent(item -> {                        
                    // remove it from the Point
                    robo.getCurrentLocation().setItem(null);
                    // add it to Robo
                    robo.setCarried(item);
                });
            
        }
    }, DROP {
        void execute(Robo robo) {
            // get the optional carried item from Robo
            robo.getCarried()                    
                .ifPresent(item -> {
                    // remove it from Robo
                    robo.setCarried(null);
                    // add it to the Point
                    robo.getCurrentLocation().setItem(item);
                });
        }
    };

    abstract void execute(Robo robo);
    
}

关于领域设计的一些想法。

我想将 FloorMap 设计为点的集合,而不是数组。只有持有物品或已被机器人访问过的点才会存在于集合中。

class FloorMap {
    Set<Point> points = new HashSet<>();       

    Point getPoint(long x, long y) {
        // looks up the point, creating a new one if necessary
        return points.stream()
            .filter(p -> p.getX() == x && p.getY() == y)
            .findAny()
            .orElse(newPoint(x, y));
    } 

    private Point newPoint(long x, long y) {
        Point point = new Point(x, y);
        points.add(point);
        return point;
    }
}

如果 Robo 经常走来走去,人们可以设想一种清理算法来删除空点。需要想办法阻止 Robo 当前访问的 Point 被清理。

Robo 将有一个 Point 作为其当前位置,引用 FloorMap 中的一个 Point,以及一个可选的 MapObject:

class Robo {
    Point currentLocation;
    FacingDirection facingDirection;
    MapObject carried;

    Robo(FloorMap floorMap) {
        currentLocation = floorMap.getPoint(0, 0);
        facingDirection = FacingDirection.UP;
    }

    Optional<MapObject> getCarried() {
        return Optional.ofNullable(carried);
    } 
}

积分会有一个可选项目:

class Point{
    long x;
    long y;
    MapObject item;

    Point(long x, long y) {
        this.x = x;
        this.y = y;
    }

    Optional<MapObject> getItem() {
        return Optional.ofNullable(mapObject);
    } 
}

我设计中的 FacingDirection 枚举具有 delta 方法来指示 x 和 y 坐标的更改,以及返回新 FacingDirection 的左/右方法:

enum FacingDirection {
    UP() {
        int deltaX() {
            return 0;
        }
        int deltaY()  {
            return 1;
        }
        FacingDirection left() {
            return LEFT;
        }
        FacingDirection right() {
            return RIGHT;
        }
    },
    RIGHT() {
        int deltaX() {
            return 1;
        }
        int deltaY()  {
            return 0;
        }
        FacingDirection left() {
            return UP;
        }
        FacingDirection right() {
            return DOWN;
        }
    },
    // etc...

    abstract int deltaX();
    abstract int deltaY();
    abstract FacingDirection left();
    abstract FacingDirection right();
}
© www.soinside.com 2019 - 2024. All rights reserved.