ソフトウェア-deleted-開発は抽象化の芸術です。あなたは論理の部分の間の類似点を見て、それらを抽象化するためのスキルを開発しようとするべきです。たとえば、移動が合法であるかどうかをチェックするには、同じチェックロジックを適用して異なる方向にセルから反復処理を行う必要があります。さらに、移動のチェックと移動の適用(ピースのフリッピング)は、同じ反復ロジックを共有します。
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
メソッドは、ある方向を受け入れ、空のセルまたは境界に達するまでナビゲートします。空でない各セルに対して、CellHandler
のhandleCell
が呼び出されます。ですから今度はcheckLegalPlay
がシンプルになります:CheckCellHandler
を実装し、可能なすべての方向を反復してその方向に反転できるかどうかを確認してください。実際のフリップロジックの実装は実際には非常に似ています。単にFlipCellHandler
を実装して同様に使用します。 myIcon
とotherIcon
を明示的にハンドラに渡すことによって、 "現在のプレーヤー"を抽象化することもできます。
セル内の色を表すために隣接関係のリストとブール値のリストを作成し、再帰的に反復し、繰り返しにいくつかの条件を追加することができます。 – Yahya
私は、リストを繰り返し再帰的に反復する方法についてはまだ混乱しています。 @ヤヒヤ –