@Override
 public void findControlledStacks(String boardSpace) {
   Tile boardTile = new Tile();
   boardTile = boardTile.stringToTile(boardSpace);
   if (boardTile.getColor() == 'W') {
     int newScore = getScore() + boardTile.getPipsLeftEnd() + boardTile.getPipsRightEnd();
     setScore(newScore);
   }
 }
 /**
  * Checks to see whether the computer has any moves available with the chosen tile from its hand.
  *
  * @param cpuSelectTile A Tile object that the computer player chose from its hand.
  * @param gameBoard A Board object that holds all the tiles currently on the board.
  * @return True if there is at least one possible move, false otherwise.
  */
 public boolean canCPUMakeMove(Tile cpuSelectTile, Board gameBoard) {
   boolean makeMove = false;
   Tile boardTile = new Tile();
   for (int space = 0; space < gameBoard.getAllBoardSpaces().size(); space++) {
     if (isValidMove(cpuSelectTile, boardTile.stringToTile(gameBoard.getBoardStacks().get(space)))
         == true) {
       makeMove = true;
       break;
     }
   }
   return makeMove;
 }
 /**
  * Creates an ArrayList of integers that represent the best possible moves on the board for a
  * given tile.
  *
  * @param cpuSelectedTile A Tile object that the computer player chose from its hand.
  * @param gameBoard A Board object that holds all the tiles currently on the board.
  * @return bestMove An ArrayList of integers whose values represent the desirability of a move at
  *     each location on the board. The higher the number the more desirable the move.
  */
 public ArrayList<Integer> calculateBestMoveVector(Tile cpuSelectedTile, Board gameBoard) {
   ArrayList<Integer> bestMove = new ArrayList<Integer>();
   for (int space = 0; space < gameBoard.getBoardStacks().size(); space++) {
     Tile boardTile = new Tile();
     // Get boardTile from the game board.
     String boardTileString = gameBoard.getBoardStacks().get(space);
     // Convert the tile from string to Tile.
     boardTile = boardTile.stringToTile(boardTileString);
     int moveScore = 0;
     // Positive score computer tile on human tile.
     if (cpuSelectedTile.getColor() == 'W' && boardTile.getColor() == 'B') {
       moveScore =
           (cpuSelectedTile.getPipsLeftEnd() + cpuSelectedTile.getPipsRightEnd())
               + (boardTile.getPipsLeftEnd() + boardTile.getPipsRightEnd());
     }
     // Negative score computer tile on own computer tile.
     else if (cpuSelectedTile.getColor() == 'W' && boardTile.getColor() == 'W') {
       moveScore =
           (cpuSelectedTile.getPipsLeftEnd() + cpuSelectedTile.getPipsRightEnd())
               - (boardTile.getPipsLeftEnd() + boardTile.getPipsRightEnd())
               - 10;
     }
     // This is for help function, positive score human tile on computer tile.
     else if (cpuSelectedTile.getColor() == 'B' && boardTile.getColor() == 'W') {
       moveScore =
           (cpuSelectedTile.getPipsLeftEnd() + cpuSelectedTile.getPipsRightEnd())
               + (boardTile.getPipsLeftEnd() + boardTile.getPipsRightEnd());
     }
     // Also for help function, negative score human tile on own human tile.
     else if (cpuSelectedTile.getColor() == 'B' && boardTile.getColor() == 'B') {
       moveScore =
           (cpuSelectedTile.getPipsLeftEnd() + cpuSelectedTile.getPipsRightEnd())
               - (boardTile.getPipsLeftEnd() + boardTile.getPipsRightEnd())
               - 10;
     }
     bestMove.add(moveScore);
   }
   return bestMove;
 }
  /**
   * Performs the action of the computer player choosing a tile, choosing a location, and then
   * executing the move if possible. Also used for help function to determine best move for human
   * player but a move will not be executed.
   *
   * @param gameBoard A Board object that holds all the tiles currently on the board.
   * @param help Boolean value used to determine if this is being used for the computer's move or
   *     help functionality. It is set to true if used for the help functionality, false for the
   *     computer's turn.
   * @return True if a move was executed. A return value of false means no moves were possible and
   *     the computer must pass or a help recommendation will be to pass.
   * @throws Exception if an invalid tile or location is specified for placeTile function.
   */
  public boolean playTile(Board gameBoard, boolean help) throws Exception {
    int handLocation = 0;
    boolean canMove = false;

    while (handLocation < getHand().size()) {
      // Select tile from hand.
      Tile cpuTile = new Tile(selectTileToPlay(handLocation));
      // See if any moves are possible with that tile.
      boolean possibleMove = canCPUMakeMove(cpuTile, gameBoard);

      if (possibleMove == true) {
        ArrayList<Integer> bestMove =
            new ArrayList<Integer>(calculateBestMoveVector(cpuTile, gameBoard));
        boolean foundLocation;
        do {
          // Select location to play tile.
          String cpuLocation = selectLocationToPlay(gameBoard, bestMove);

          // See if selected location would yield a valid move.
          Tile boardTile = new Tile();
          if (isValidMove(cpuTile, boardTile.stringToTile(gameBoard.getBoardTile(cpuLocation)))
              == true) {
            // Record the tile played, tile replaced, and location for display purposes.
            setTilePlayed(cpuTile);
            setTileReplaced(boardTile.stringToTile(gameBoard.getBoardTile(cpuLocation)));
            setLocationReplaced(cpuLocation);
            // Flag to skip this step if this is for the user's help function
            if (help == false) {
              // To prevent the computer from placing a non-double tile on its own tile if it has a
              // double tile it can play.
              if (!(gameBoard.getBoardTile(cpuLocation).startsWith("W")
                  && handLocation != (getHand().size() - 1))) {
                placeTile(gameBoard, cpuLocation, cpuTile);
                foundLocation = true;
              } else {
                foundLocation = false;
                break;
              }
            } else {
              // Same as above to prevent from placing non-double tile on its own tile if double
              // tile can be played, but for help mode.
              if (!(gameBoard.getBoardTile(cpuLocation).startsWith("B")
                  && handLocation != (getHand().size() - 1))) {
                foundLocation = true;
              } else {
                foundLocation = false;
                break;
              }
            }
          } else {
            // Selected location and tile combination was not a valid move.
            foundLocation = false;
          }
        } while (foundLocation == false);

        // A location was found and a move was made.
        if (foundLocation == true) {
          canMove = true;
          break;
        }
        // Chooses the next tile in the hand.
        else {
          handLocation++;
        }

      }
      // The selected tile was unplayable.
      else {
        handLocation++;
        canMove = false;
      }
    }
    return canMove;
  }