我正在开发一个基本机器人应用程序的项目。我正在使用一些类和枚举,并且要使用我的枚举来移动,在这里我有点困惑。 所以我现在正在研究我的主要课程 - 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。感谢您的宝贵时间,并提前感谢您提供任何帮助/提示。
您没有提供完整的信息,因此有一些假设:
例如,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();
}