我正在制作国际象棋游戏,我正在使用“单位矢量”来处理棋子移动的方向。
例如。 pawn通常具有单位向量(0,1),因为它只能向前移动一个空格。
因此我创建了许多保存相同数据的实例。为了防止这种情况并防止系统资源的浪费,我决定持有一个中央查找表来保存可以在电路板上使用的所有位置向量的列表(9x9)
最好的方法是什么?因为我不能只有一组这些向量并找到一个没有迭代的具有相同解析的笛卡尔点的向量,我想避免
答案 0 :(得分:1)
首先,请记住......
“我们应该忘记效率低下,大约97%的时间说:过早的优化是所有邪恶的根源。”
因此,以允许这种优化的方式设计您的运动矢量类是谨慎的,但是在事情相当有效之前推迟实际执行它。
尽管如此,并不是那么难(并且彻底的单元测试可以确保您的优化不会引入任何错误)。最简单的方法是使用Map<Integer, Map<Integer, A>>
或Map<String, A>
,其中A
是您的运动矢量类。你可以这样实现它:
public class MovementVector {
private static Map<String, MovementVector> cache = new HashMap<>();
//Step 0 : all fields must be immutable, or instance sharing will backfire catastrophically
public final int r;
public final int c;
//Step 1 : make constructor(s) private so new instances can't be created without your knowledge
private MovementVector(int r, int c) {
this.r = r;
this.c = c;
}
public String toString() {
return makeString(r, c);
}
//Step 2 : single method that makes keys for a given r,c.
// Must be static so it can be used in get(..) below.
private static String makeString(int r, int c) {
return "(" + r + "," + c + ")";
}
public boolean equals(Object o) {
if (! (o instanceof MovementVector)) return false;
MovementVector m = (MovementVector)o;
return r == m.r && c == m.c;
}
public int hashCode() {
return r * 10 + c;
}
//Step 3 : public static getter that functions as constructor/instance retriever
public static MovementVector get(int r, int c) {
String str = makeString(r,c);
MovementVector vectorFromCache = cache.get(str);
if (vectorFromCache != null) return vectorFromCache;
else {
MovementVector v = new MovementVector(r,c);
cache.put(str, v);
return v;
}
}
}
用法:
MovementVector pawnMovement = MovementVector.get(0,1);
MovementVector pawnMovement2 = MovementVector.get(0,1);
//pawnMovement == pawnMovement2