@Override
	public Coordinate performNextShot() {
		Coordinate coord = null;
		
		if (hitCoordinates.size() == 1) {
			List<Tile> neumannNeighbors = field.getNeumannNeighbors(hitCoordinates.get(0));
			List<Tile> neighborsWithUnknownState = getTilesWithUnknownState(neumannNeighbors);
			
			Random random = new Random();
			int tileIndex = random.nextInt(neighborsWithUnknownState.size());
			coord = neighborsWithUnknownState.get(tileIndex).getCoordinate();
		} else if (hitCoordinates.size() >= 2) {
			if (lastShotResult == EServerResult.Water) {
				searchVector = new int[] { -searchVector[0], -searchVector[1] };
				coord = hitCoordinates.get(0).add(searchVector[0], searchVector[1]);
			} else {
				Coordinate lastHitCoord = hitCoordinates.get(hitCoordinates.size() - 1);
				coord = lastHitCoord.add(searchVector[0], searchVector[1]);
			}
		}
		
		lastShotResult = server.shot(coord);
		
		if (lastShotResult == EServerResult.Hit 
			|| lastShotResult == EServerResult.Sunk 
			|| lastShotResult == EServerResult.Won) {
			
			field.setTileState(coord, ETileState.Ship);
			field.setDiagonalNeighborsWater(coord);
			
			if (hitCoordinates.size() == 1) {
				calculateSearchVector(coord);
			}
			
			hitCoordinates.add(coord);
			
			// When ship is sunk the next tile in direction of search vector has to be water
			if (lastShotResult == EServerResult.Sunk
				|| lastShotResult == EServerResult.Won) {
				
				Coordinate waterTile = coord.add(searchVector[0], searchVector[1]);
				field.setTileState(waterTile, ETileState.Water);
			}
		} else {
			field.setTileState(coord, ETileState.Water);
		}
		
		return coord;
	}