我一直在使用Java实现黑白棋游戏,这是为了进行研究,并且需要一个快速的实现来运行尽可能多的游戏。所以这是我所做的:
Board[][]实现
我的第一个方法是使用board [][ ] 多维数组来表示棋盘,只是为了让它工作,并确保它正常工作。我完成了它,感到很高兴。但是,大多数人都知道,那不太快,因为我只能玩1500个游戏每秒(随机移动,仅供测试)。
Bitboard
然后,我将棋盘实现为BitBoard,这大大加快了移动计算速度,与先前的实现相比,速度非常快。使用此实现,它可以每秒播放多达20,000个游戏。这是我用于移动计算的代码,它非常好用,但重复:
private void calculateMoves() {
legal = 0L;
long potentialMoves;
long currentBoard = getCurrentBoard();
long opponentBoard = getOpponentBoard();
long emptyBoard = emptyBoard();
// UP
potentialMoves = (currentBoard >> SIZE) & DOWN_MASK & opponentBoard;
while (potentialMoves != 0L) {
long tmp = (potentialMoves >> SIZE) & DOWN_MASK;
legal |= tmp & emptyBoard;
potentialMoves = tmp & opponentBoard;
}
// DOWN
potentialMoves = (currentBoard << SIZE) & UP_MASK & opponentBoard;
while (potentialMoves != 0L) {
long tmp = (potentialMoves << SIZE) & UP_MASK;
legal |= tmp & emptyBoard;
potentialMoves = tmp & opponentBoard;
}
// LEFT
potentialMoves = (currentBoard >> 1L) & RIGHT_MASK & opponentBoard;
while (potentialMoves != 0L) {
long tmp = (potentialMoves >> 1L) & RIGHT_MASK;
legal |= tmp & emptyBoard;
potentialMoves = tmp & opponentBoard;
}
// RIGHT
potentialMoves = (currentBoard << 1L) & LEFT_MASK & opponentBoard;
while (potentialMoves != 0L) {
long tmp = (potentialMoves << 1L) & LEFT_MASK;
legal |= tmp & emptyBoard;
potentialMoves = tmp & opponentBoard;
}
// UP LEFT
potentialMoves = (currentBoard >> (SIZE + 1L)) & RIGHT_MASK & DOWN_MASK & opponentBoard;
while (potentialMoves != 0L) {
long tmp = (potentialMoves >> (SIZE + 1L)) & RIGHT_MASK & DOWN_MASK;
legal |= tmp & emptyBoard;
potentialMoves = tmp & opponentBoard;
}
// UP RIGHT
potentialMoves = (currentBoard >> (SIZE - 1L)) & LEFT_MASK & DOWN_MASK & opponentBoard;
while (potentialMoves != 0L) {
long tmp = (potentialMoves >> (SIZE - 1L)) & LEFT_MASK & DOWN_MASK;
legal |= tmp & emptyBoard;
potentialMoves = tmp & opponentBoard;
}
// DOWN LEFT
potentialMoves = (currentBoard << (SIZE - 1L)) & RIGHT_MASK & UP_MASK & opponentBoard;
while (potentialMoves != 0L) {
long tmp = (potentialMoves << (SIZE - 1L)) & RIGHT_MASK & UP_MASK;
legal |= tmp & emptyBoard;
potentialMoves = tmp & opponentBoard;
}
// DOWN RIGHT
potentialMoves = (currentBoard << (SIZE + 1L)) & LEFT_MASK & UP_MASK & opponentBoard;
while (potentialMoves != 0L) {
long tmp = (potentialMoves << (SIZE + 1L)) & LEFT_MASK & UP_MASK;
legal |= tmp & emptyBoard;
potentialMoves = tmp & opponentBoard;
}
moves.clear();
}
类
然后我尝试用以下方式对代码进行了一些清理:
private MoveFinder[] finders = new MoveFinder[] {new UpFinder(), new DownFinder(), new LeftFinder(),
new RightFinder(), new UpLeftFinder(), new UpRightFinder(), new DownLeftFinder(), new DownRightFinder()};
private void calculateMoves() {
legal = 0L;
long potentialMoves;
long currentBoard = getCurrentBoard();
long opponentBoard = getOpponentBoard();
long emptyBoard = emptyBoard();
for (MoveFinder finder : finders) {
potentialMoves = finder.next(currentBoard) & opponentBoard;
while (potentialMoves != 0L) {
long tmp = finder.next(potentialMoves);
legal |= tmp & emptyBoard;
potentialMoves = tmp & opponentBoard;
}
}
moves.clear();
}
private interface MoveFinder {
long next(long next);
}
private class UpFinder implements MoveFinder {
@Override
public long next(long n) {
return (n >> SIZE) & DOWN_MASK;
}
}
private class DownFinder implements MoveFinder {
@Override
public long next(long n) {
return (n << SIZE) & UP_MASK;
}
}
// and so on for the rest of the moves (LeftFinder, RightFinder, etc).
出于某种原因,采用这种方法我只能每秒运行15k个游戏!为什么这段代码要慢得多?Java方法调用很昂贵吗?是因为从数组中调用对象吗?还是因为我为每个方法传递了长整型n的副本?如果您有任何想法,请告诉我,因为我不太擅长优化代码。谢谢!