Object Oriented Design

Today we’re going over the strategy pattern.

class Coord {
  int row;
  int col
}
interface TicTacToeStrategy {
  Coord chooseMove(TicTacToeModel model, Piece forWhom);
}
class AnyOpenSquare implements TicTacToeStrategy {
  public Coord chooseMove(TicTacToeModel model, Piece forWhom) {
    for (int r = 0; r < 3; r++)
      for (int c = 0; c < 3; c++)
        if (model.getPieceAt(r, c) == null)
          return new Coord(r, c);
    return null;
  }
}
class AnyOpenCorner implements TicTacToeStrategy {
  public Coord chooseMove(TicTacToeModel model, Piece forWhom) {
    if (model.getPieceAt(0, 0) == null)      return new Coord(0, 0);
    else if (model.getPieceAt(0, 2) == null) return new Coord(0, 2);
    else if (model.getPieceAt(2, 0) == null) return new Coord(2, 0);
    else if (model.getPieceAt(2, 2) == null) return new Coord(2, 2);
    else                                     return null;
  }
}
class TryTwo implements TicTacToeStrategy {
  TicTacToeStrategy first, second;
  public Coord chooseMove(TicTacToeModel model, Piece forWhom) {
    Coord ans = this.first.chooseMove(model, forWhom);
    if (ans != null) return ans; // the first strategy succeeded
    return this.second.chooseMove(model, forWhom);
  }
}
User computerUser = ...;
Strategy easy = new TryTwo(new PlayToWin(), new AnyOpenSquare());
Strategy medium = new TryTwo(new PlayToWin(), new TryTwo(new DontLose(), new AnyOpenSquare()));
Strategy hard = new TryTwo(new PlayToWin(),
                  new TryTwo(new DontLose(),
                    new TryTwo(new AnyOpenCorner(), new AnyOpenSquare())));
if (difficulty == EASY)
  computerUser.playStrategy(easy);
else if (difficulty == MEDIUM)
  computerUser.playStrategy(medium);
else
  computerUser.playStrategy(hard);