/*
   *
   * Selected
   *
   * 	A				A/B
   * 	B		=>		A/C
   * 	C				B/A
   * 					B/C
   * 					C/A
   * 					C/B
   *
   */
  public Collection<InfiniteBoard> spliceBoards(Collection<InfiniteBoard> selectedBoards) {
    Random rand = new Random();

    boards = new TreeSet<InfiniteBoard>();

    for (InfiniteBoard b1 : selectedBoards) {
      for (InfiniteBoard b2 : selectedBoards) {
        if (b1 != b2) {

          int direction = rand.nextInt(2);
          int boundary;
          if (direction == 0) { // Horizontal boundary
            boundary = rand.nextInt(height);
          } else { // Vertical boundary
            boundary = rand.nextInt(width);
          }

          InfiniteBoard newBoard = new InfiniteBoard(height, width);
          for (Cell cell : b1.getCellsMap().values()) {
            if (cell.isAlive()) {
              if (direction == 0) { // horizontal boundary
                if (cell.getCoord().getX() >= boundary) {
                  newBoard.setAlive(cell.getCoord().getX(), cell.getCoord().getY(), true);
                }
              } else { // vertical boundary
                if (cell.getCoord().getY() >= boundary) {
                  newBoard.setAlive(cell.getCoord().getX(), cell.getCoord().getY(), true);
                }
              }
            }
          }

          for (Cell cell : b2.getCellsMap().values()) {
            if (cell.isAlive()) {
              if (direction == 0) { // horizontal boundary
                if (cell.getCoord().getX() < boundary) {
                  newBoard.setAlive(cell.getCoord().getX(), cell.getCoord().getY(), true);
                }
              } else { // vertical boundary
                if (cell.getCoord().getY() < boundary) {
                  newBoard.setAlive(cell.getCoord().getX(), cell.getCoord().getY(), true);
                }
              }
            }
          }

          if (boards.size() < this.numBoards) {
            boards.add(newBoard);
          }
        }
      }
    }
    return boards;
  }
  private void selectSplice() {
    // SELECT BEST HEURISTIC BOARDS

    // Trim off the worst boards.
    while (boards.size() > this.chooseBest) {
      boards.remove(boards.first());
    }

    // Add all boards to the "keep" list, then trim off the worst so we only
    // keep as many as the "keepBest" parameter.
    this.bestBoards.addAll(boards);
    while (bestBoards.size() > keepBest) {
      bestBoards.remove(bestBoards.first());
    }

    // REWIND BOARDS
    for (InfiniteBoard b : boards) {
      b.rewindBoard();
    }

    // SPLICE BOARDS
    spliceBoards(boards);
  }