package murex.pop.dojo.reversi; import static murex.pop.dojo.reversi.Position.position; import java.util.List; import com.google.common.base.Function; import com.google.common.collect.FluentIterable; import com.google.common.collect.ImmutableList; public class Board { public static final char _ = '.'; public static final char B = 'B'; public static final char W = 'W'; private final char[][] cells; public Board(char[]... cells) { this.cells = cells; } public List<Position> legalMovesFor(char color) { final ImmutableList.Builder<Position> result = ImmutableList.builder(); for (int iLine = 0; iLine < cells.length; ++iLine) { for (int iColumn = 0; iColumn < cells[iLine].length; ++iColumn) { final Position currentPosition = position(iLine, iColumn); if (isValidPosition(color, currentPosition)) { result.add(currentPosition); } } } return result.build(); } private boolean isValidPosition(char color, Position position) { return colorAt(position) == _ && isNotSurroundByItsOwnColor(color, position); } private char colorAt(Position position) { return cells[position.line()][position.column()]; } private boolean isNotSurroundByItsOwnColor(char color, Position position) { return neighboursOf(position).transform(toColor()).contains(other(color)); } private FluentIterable<Position> neighboursOf(Position position) { int iLine = position.line(); int iColumn = position.column(); final ImmutableList.Builder<Position> builder = ImmutableList.builder(); for (int i = Math.max(iLine - 1, 0); i <= Math.min(iLine + 1, cells.length - 1); i++) { for (int j = Math.max(iColumn - 1, 0); j <= Math.min(iColumn + 1, cells[i].length - 1); j++) { builder.add(position(i, j)); } } return FluentIterable.from(builder.build()); } private Function<? super Position, Character> toColor() { return new Function<Position, Character>() { @Override public Character apply(Position position) { return colorAt(position); } }; } private static char other(char color) { switch (color) { case B: return W; case W: return B; default: throw new UnsupportedOperationException(); } } }