public void crossoverWith(DesignBoard b) {
    if (width != b.width || height != b.height) {
      throw new RuntimeException("Trying to crossover boards that have different dimensions.");
    }

    boolean isVerticalSplit = parameters.random.nextBoolean();

    // This gives a range slightly in from the maxHeight or maxWidth.
    // For example, if the maxWidth is 10, this gives us a range of 1 - 8 instead of 0 - 9.
    int max = isVerticalSplit ? width : height;
    int splitEnd = parameters.random.nextInt(max - 1) + 1;

    int length = isVerticalSplit ? height : width;
    for (int i = 0; i < splitEnd; i++) {
      for (int j = 0; j < length; j++) {
        int x = i;
        int y = j;
        if (!isVerticalSplit) {
          x = j;
          y = i;
        }

        // Swap the values.
        DesignCell temp = get(x, y);
        set(x, y, b.get(x, y));
        b.set(x, y, temp);
      }
    }
  }
  public DesignBoard(DesignBoard designBoardToCopy) {
    this.width = designBoardToCopy.width;
    this.height = designBoardToCopy.height;
    this.parameters = designBoardToCopy.parameters;
    this.board = new ArrayList<>(width * height);

    // Copy the cell type and
    for (int y = 0; y < height; y++) {
      for (int x = 0; x < width; x++) {
        board.add(new DesignCell(designBoardToCopy.get(x, y)));
      }
    }
  }