我正在用Java编写2048游戏和自解算器。我最重要的课程是Board
,其中包含主要的游戏功能。出于效率原因,游戏的许多方面都以数组编码,例如当向左或向右移动时每个可能行的变换。在static
初始化块中,我调用static void generateTables()
,它会创建一次表。
具有求解功能extend
Board
和implement
Solver
的论坛,包含使用高级方法getDirection()
和getWorstLocation()
的界面通过接口类来运行解算器并获取提示。我感兴趣的主要解算器类型记录了所有可能行的启发式值列表,然后使用这些值运行expectiminimax搜索。所以我有课:
public class HeuristicBoard extends Board implements Solver {
private static int[] heuristic; // Lookup table
/* ... methods omitted ... */
private int heuristic() {...}
// Calculates a heuristic value for the entire board based
// on calls to the following method
// This method's code could change depending on algorithm implementation.
private static int heuristic(short row) {...}
// Checks the lookup table for the row provided
private static void generateHeuristicTable() {...}
// Generates the lookup table based on calls to the following method
private static int heuristic(byte[] row) {...}
// Calculates the heuristic value for a single row.
// This method's code could change depending on algorithm implementation.
}
现在,我想测试多种不同的启发式方法,但使用相同的expectiminimax算法。因此,int heuristic()
和static int heuristic(byte[] row)
的实现会发生变化,而其他实现则会保持不变。抽象HeuristicBoard
类的功能以便有多个实现int heuristic()
和static int heuristic(byte[] row)
的子(?)类的最佳方法是什么?他们最好有一个共同的祖先,所以我可以:
ClassOrInterface firstSolver = new EmptySpaceHeuristicBoard();
ClassOrInterface secondSolver = new MonotonicityHeuristicBoard();
我已经想到并在各种StackOverflow答案中看到了建议:
制作HeuristicBoard
abstract
并制作两种方法abstract
。但出于某种原因(是的,我已经阅读了原因)你不能拥有static abstract
方法。如果我使static int heuristic(byte[] row)
非静态,我将无法在static void generateHeuristicTable()
方法中使用它,这应该在HeuristicBoard
类中实现,而不是在子类中实现(我会在每个子类中重新实现它,每次只更改一次性new SubclassOfHeuristicBoard().heuristic(currentRow)
。如果我也使这个方法非静态,忽略上面所示的不便,那么我将无法调用generateHeuristicTable()
在static
初始化块中,从而使得每个新的类实例都会生成(大)表。
创建一个包含静态方法的HeuristicSolver
接口,然后HeuristicBoard
implement
HeuristicSolver
,然后继承HeuristicBoard
。但是,这迫使我提供静态方法的默认实现,我认为这没有道理。只应该实例化子类,因为只有它们应该提供启发式实现。此外,类中的其他静态方法仅引用Board
类中的静态变量。
还有其他可能性,但在使HeuristicBoard
非抽象后,它们真的会变得更糟。
在我看来,唯一正确的方法是制作HeuristicBoard
abstract
,但我无法弄清楚如何使用static
方法。
编辑:已经指出两种方法都可以更改为non-static
。这解决了上述问题,但现在我有另一个问题:在非静态AI方法中,我复制了板以用于递归目的:HeuristicBoard option = new HeuristicBoard(board)
。但是,如果这个类是抽象的,我就不能这样做。我应该如何创建当前类的实例? (即在EmptySpaceHeuristicBoard
类中,当继承并执行此方法时,它应创建new EmptySpaceHeuristicBoard()
。
答案 0 :(得分:0)
有几点意见:
静态方法总是可以实现为不使用任何实例变量的实例方法,这样就可以解决您的问题而无法覆盖静态方法。
我不明白为什么启发式板会扩展板。我认为让一个像scoreBoard()
这样的方法的Solver类更有意义。
2048不是一个极小极大的游戏,因为对手'没有选择' min'选项,而是随机选项。因此,要使用的优化器是expectimax。