private Set<Pos> possiblesMovesAroundASpecificPosition(Pos pos) {
    HashSet<Pos> listOfCellAroundASpecificPosition = new HashSet<Pos>();
    int x = pos.getXCoord(), y = pos.getYCoord();

    // We must check if positions around the first one aren't out of the
    // grid and are navigable.
    if (x + 1 < this.gridWidth
        && getCellAtSpecificsCoords(x + 1, y).getCellSurface().canWalkOnSurface()
        && !listOfCellAroundASpecificPosition.contains(pos.newPos(1, 0))) {
      listOfCellAroundASpecificPosition.add(pos.newPos(1, 0));
    }

    if (x - 1 >= 0
        && getCellAtSpecificsCoords(x - 1, y).getCellSurface().canWalkOnSurface()
        && !listOfCellAroundASpecificPosition.contains(pos.newPos(-1, 0))) {
      listOfCellAroundASpecificPosition.add(pos.newPos(-1, 0));
    }

    if (y + 1 < this.gridHeight
        && getCellAtSpecificsCoords(x, y + 1).getCellSurface().canWalkOnSurface()
        && !listOfCellAroundASpecificPosition.contains(pos.newPos(0, 1))) {
      listOfCellAroundASpecificPosition.add(pos.newPos(0, 1));
    }

    if (y - 1 >= 0
        && getCellAtSpecificsCoords(x, y - 1).getCellSurface().canWalkOnSurface()
        && !listOfCellAroundASpecificPosition.contains(pos.newPos(0, -1))) {
      listOfCellAroundASpecificPosition.add(pos.newPos(0, -1));
    }

    return listOfCellAroundASpecificPosition;
  }
  public boolean attackAUnit(Pos unit1Position, Pos unit2Position) {

    List<Pos> cellsInRange = new LinkedList<Pos>();
    cellsInRange = possiblesAttackCellsAroundASpecificPosition(unit1Position);
    Unit selectedUnit1 = getCellAtASpecificPos(unit1Position).getUnitOnThisCell();
    Unit selectedUnit2 = getCellAtASpecificPos(unit2Position).getUnitOnThisCell();

    for (int index = 0; index < cellsInRange.size(); index++) {
      for (int index2 = index + 1; index2 < cellsInRange.size(); index2++) {
        if (cellsInRange.get(index2).equals(cellsInRange.get(index))) cellsInRange.remove(index2);
      }
    }

    if (getCellAtASpecificPos(unit2Position).getUnitOnThisCell() != null
        && !unit1Position.equals(unit2Position)) {
      if (!cellsInRange.contains(unit2Position)) {
        return false;
      } else {
        selectedUnit2.setLife(selectedUnit2.getLife() - selectedUnit1.getAttackDamage());
        if (selectedUnit2.getLife() <= 0) {
          getCellAtASpecificPos(unit2Position)
              .getUnitOnThisCell()
              .getOwner()
              .removeOneUnitToPlayerCounter();
          getCellAtASpecificPos(unit2Position).removeUnitFromThisCell();
        }
        return true;
      }
    }
    return false;
  }
  /**
   * Moves a selected unit to another cell.
   *
   * @param initialPosition
   * @param endPosition
   * @return True if the unit has been moved, false otherwise.
   */
  public boolean moveAUnit(Pos initialPosition, Pos endPosition) {

    Unit selectedUnit = getCellAtASpecificPos(initialPosition).getUnitOnThisCell();

    int counter = 0;
    List<Pos> reachableCells = new LinkedList<Pos>();
    HashSet<Pos> setTemp = new HashSet<Pos>();
    // setTemp allows to avoid duplicates.
    setTemp.addAll(possiblesMoves(initialPosition));
    reachableCells.addAll(setTemp);

    if (selectedUnit != null
        && !initialPosition.equals(endPosition)
        && getCellAtASpecificPos(endPosition).getUnitOnThisCell() == null) {
      // We must check if the final position is not the initial one, and
      // if the final position is empty.
      while (counter < reachableCells.size() && !reachableCells.get(counter).equals(endPosition)) {
        // Then we check is the final position is in the list of every
        // reachable cells.
        counter++;
      }

      if (counter > reachableCells.size() - 1) {
        // endPosition isn't in reachableCells.
        counter = 0;
        reachableCells.clear();
        return false;
      } else {
        // endPosition is in reachableCells.
        getCellAtASpecificPos(initialPosition).removeUnitFromThisCell();
        getCellAtASpecificPos(endPosition).setUnitOnASpecificCell(selectedUnit, endPosition);
        counter = 0;
        reachableCells.clear();
        return true;
      }
    }

    return false;
  }
 public Cell getCellAtASpecificPos(Pos pos) {
   return grid[pos.getXCoord()][pos.getYCoord()];
 }
  private List<Pos> possiblesAttackCellsAroundASpecificPosition(Pos unitPosition) {
    List<Pos> listOfPos = new LinkedList<Pos>();
    List<Pos> listOfPosInRange = new LinkedList<Pos>();
    int coordXErrorValue, coordYErrorValue, errorValue, counter = 0;

    listOfPosInRange = cellInRangeOfAttack(unitPosition);
    for (int index = 0; index < listOfPosInRange.size(); index++) {
      for (int index2 = index + 1; index2 < listOfPosInRange.size(); index2++) {
        if (listOfPosInRange.get(index2).equals(listOfPosInRange.get(index)))
          listOfPosInRange.remove(index2);
      }
    }
    // The following algorithm is pretty hard to understand and to explain.
    // If you want understand it :
    // http://fr.wikipedia.org/wiki/Algorithme_de_trac%C3%A9_de_segment_de_Bresenham
    // I had to set it, because it wasn't able to work for every situation.
    while (counter < listOfPosInRange.size()) {
      int unitXCoord = unitPosition.getXCoord(), unitYCoord = unitPosition.getYCoord();
      int cellXCoord = listOfPosInRange.get(counter).getXCoord(),
          cellYCoord = listOfPosInRange.get(counter).getYCoord();
      // Searching for case according to the X coordinates if
      // |unitXCoord-cellXCoord|>|unitYCorod-cellY|.
      if (Math.abs(unitXCoord - cellXCoord) > Math.abs(unitYCoord - cellYCoord)) {
        errorValue = Math.abs(unitXCoord - cellXCoord);
        coordXErrorValue = errorValue * 2;
        coordYErrorValue = Math.abs(unitYCoord - cellYCoord) * 2;
        // To avoid sign problems, we check if x2>=x1
        if (cellXCoord >= unitXCoord) {
          while (unitXCoord <= cellXCoord
              && getCellAtSpecificsCoords(unitXCoord, unitYCoord)
                  .getCellSurface()
                  .canFireThrough()) {
            listOfPos.add(new Pos(unitXCoord, unitYCoord));
            unitXCoord++;
            errorValue -= coordYErrorValue;
            if (errorValue <= 0 && unitXCoord <= this.gridHeight) {
              if (errorValue == 0
                  && getCellAtSpecificsCoords(cellXCoord, cellYCoord)
                      .getCellSurface()
                      .canFireThrough()) listOfPos.add(new Pos(unitXCoord, unitYCoord));
              unitYCoord++;
              errorValue += coordXErrorValue;
            }
            if (unitYCoord > this.gridWidth || unitXCoord > this.gridHeight) break;
          }
        } else {
          while (cellXCoord <= unitXCoord
              && getCellAtSpecificsCoords(unitXCoord, unitYCoord)
                  .getCellSurface()
                  .canFireThrough()) {
            listOfPos.add(new Pos(unitXCoord, unitYCoord));
            unitXCoord--;
            errorValue -= coordYErrorValue;
            if (errorValue <= 0 && unitXCoord >= 0) {
              if (errorValue == 0
                  && getCellAtSpecificsCoords(unitXCoord, unitYCoord)
                      .getCellSurface()
                      .canFireThrough()) listOfPos.add(new Pos(unitXCoord, unitYCoord));
              unitYCoord--;
              errorValue += coordXErrorValue;
            }
            if (unitYCoord < 0 || unitXCoord < 0) break;
          }
        }
      }

      // Else, do according to the Y coordinate
      else {

        errorValue = Math.abs(unitYCoord - cellYCoord);
        coordXErrorValue = errorValue * 2;
        coordYErrorValue = Math.abs(unitXCoord - cellXCoord) * 2;
        // To avoid sign problems we check if y2>=y1
        if (cellYCoord >= unitYCoord) {
          while (unitYCoord <= cellYCoord
              && getCellAtSpecificsCoords(unitXCoord, unitYCoord)
                  .getCellSurface()
                  .canFireThrough()) {
            listOfPos.add(new Pos(unitXCoord, unitYCoord));

            unitYCoord++;
            errorValue -= coordYErrorValue;
            if (errorValue <= 0 && unitYCoord <= this.gridWidth) {
              if (errorValue == 0
                  && getCellAtSpecificsCoords(cellXCoord, cellYCoord)
                      .getCellSurface()
                      .canFireThrough()) listOfPos.add(new Pos(unitXCoord, unitYCoord));
              unitXCoord++;
              errorValue += coordXErrorValue;
            }
            if (unitXCoord > this.gridHeight || unitYCoord > this.gridWidth) break;
          }
        } else {
          while (cellYCoord <= unitYCoord
              && getCellAtSpecificsCoords(unitXCoord, unitYCoord)
                  .getCellSurface()
                  .canFireThrough()) {
            listOfPos.add(new Pos(unitXCoord, unitYCoord));
            unitYCoord--;
            errorValue -= coordYErrorValue;
            if (errorValue <= 0 && unitYCoord >= 0) {
              if (errorValue == 0
                  && getCellAtSpecificsCoords(unitXCoord, unitYCoord)
                      .getCellSurface()
                      .canFireThrough()) {
                listOfPos.add(new Pos(unitXCoord, unitYCoord));
              }
              unitXCoord--;
              errorValue += coordXErrorValue;
            }
            if (unitXCoord < 0 || unitYCoord < 0) break;
          }
        }
      }
      counter++;
    }
    return listOfPos;
  }
  private List<Pos> cellsAroundACell(Pos unitPosition) {
    List<Pos> list = new LinkedList<Pos>();
    if (unitPosition.getXCoord() + 1 <= this.gridWidth
        && getCellAtASpecificPos(unitPosition.newPos(1, 0)).getCellSurface().canWalkOnSurface()) {
      list.add(unitPosition.newPos(1, 0));
    }

    if (unitPosition.getXCoord() - 1 >= 0
        && getCellAtASpecificPos(unitPosition.newPos(-1, 0)).getCellSurface().canWalkOnSurface()) {
      list.add(unitPosition.newPos(-1, 0));
    }

    if (unitPosition.getYCoord() + 1 <= this.gridHeight
        && getCellAtASpecificPos(unitPosition.newPos(0, 1)).getCellSurface().canWalkOnSurface()) {
      list.add(unitPosition.newPos(0, 1));
    }

    if (unitPosition.getYCoord() - 1 >= 0
        && getCellAtASpecificPos(unitPosition.newPos(0, -1)).getCellSurface().canWalkOnSurface()) {
      list.add(unitPosition.newPos(0, -1));
    }
    return list;
  }