我正在尝试使用Java开发Othello游戏,我正在努力实现查找可用的移动,玩家有(而不是计算机)。
例如,我是玩家1,我在玩白色棋子,
我正在努力实现3和5。
我如何遍历所有的方向(如果我在板的内部,最多有8个方向),我怎样才能进一步检查每个方向的颜色?
我想实现所有的8个方向的内部板,然后实现所有的可能性,在外部板和检查边缘选项,这是非常不有效的,我不想那样编码。
你不需要看代码,我正在努力弄清楚如何接近它(考虑2的循环),但是下面是函数和整个代码:(每个按钮都有一个图标--黑白块)
private void checkLegalPlay(int row, int col) {
if(playerNum == 0){ //Black player
if(row > 0 && row < 7 && col > 0 && col < 7){ //Inner board -
//not good, i want from any point of the board
for(int i = col-1; i != 0; i--)
if(squares[row][i].getIcon() != null){
if(squares[row][i].getIcon() == blackPiece){
//Advance until boundary - return false
//Advance if there're black pieces
//If we get to white piece, turn all to
// white pieces
}
}
}
}
}它已经有将近300行代码了,所以如果你真的想知道我做了什么,我宁愿给出一个链接:-删除-
发布于 2017-06-24 16:45:43
软件开发是一门抽象的艺术。你应该试着发展一种技能,看看逻辑片段之间的相似之处,并把它们抽象出来。例如,要检查移动是否合法,必须应用相同的检查逻辑从单元格向不同方向迭代。此外,检查移动和应用移动(翻转块)共享相同的迭代逻辑。所以让我们把它抽象开,也就是说,让我们把迭代从逻辑中分离出来,我们在迭代中这样做:
private static final int SIZE = 8;
static boolean isValidPos(int pos) {
return pos >= 0 && pos < SIZE;
}
static class Point {
public final int row;
public final int col;
public Point(int row, int col) {
this.row = row;
this.col = col;
}
}
private static final Point[] ALL_DIRECTIONS = new Point[]{
new Point(1, 0),
new Point(1, 1),
new Point(0, 1),
new Point(-1, 1),
new Point(-1, 0),
new Point(-1, -1),
new Point(0, -1),
new Point(1, -1),
};
interface CellHandler {
boolean handleCell(int row, int col, Icon icon);
}
void iterateCells(Point start, Point step, CellHandler handler) {
for (int row = start.row + step.row, col = start.col + step.col;
isValidPos(row) && isValidPos(col);
row += step.row, col += step.col) {
Icon icon = squares[row][col].getIcon();
// empty cell
if (icon == null)
break;
// handler can stop iteration
if (!handler.handleCell(row, col, icon))
break;
}
}
static class CheckCellHandler implements CellHandler {
private final Icon otherIcon;
private boolean hasOtherPieces = false;
private boolean endsWithMine = false;
public CheckCellHandler(Icon otherIcon) {
this.otherIcon = otherIcon;
}
@Override
public boolean handleCell(int row, int column, Icon icon) {
if (icon == otherIcon) {
hasOtherPieces = true;
return true;
} else {
endsWithMine = true;
return false;
}
}
public boolean isGoodMove() {
return hasOtherPieces && endsWithMine;
}
}
class FlipCellHandler implements CellHandler {
private final Icon myIcon;
private final Icon otherIcon;
private final List<Point> currentFlipList = new ArrayList<Point>();
public FlipCellHandler(Icon myIcon, Icon otherIcon) {
this.myIcon = myIcon;
this.otherIcon = otherIcon;
}
@Override
public boolean handleCell(int row, int column, Icon icon) {
if (icon == myIcon) {
// flip all cells
for (Point p : currentFlipList) {
squares[p.row][p.col].setIcon(myIcon);
}
return false;
} else {
currentFlipList.add(new Point(row, column));
return true;
}
}
}
private boolean checkLegalPlay(int row, int col) {
ImageIcon otherIcon = (playerNum == 0) ? whitePiece : blackPiece;
Point start = new Point(row, col);
for (Point step : ALL_DIRECTIONS) {
// handler is stateful so create new for each direction
CheckCellHandler checkCellHandler = new CheckCellHandler(otherIcon);
iterateCells(start, step, checkCellHandler);
if (checkCellHandler.isGoodMove())
return true;
}
return false;
}ALL_DIRECTIONS代表您可以导航的所有8个方向。iterateCells方法接受某些方向并在其中导航,直到到达空单元格或边框。对于每个非空单元格,调用传递的handleCell的CellHandler。所以现在您的checkLegalPlay变得简单了:实现CheckCellHandler并遍历所有可能的方向,看看我们是否可以朝这个方向翻转。实现实际的翻转逻辑实际上非常相似:只需实现FlipCellHandler并以类似的方式使用它。请注意,您还可以通过显式地将myIcon和otherIcon传递给处理程序来抽象“当前播放器”。
https://stackoverflow.com/questions/44736696
复制相似问题