@Override
	public List<Tile> getDiscardCandidates(Set<Tile> aliveTiles, Collection<Tile> candidates) {
		// 先保证顺子刻子的定义都是3张牌、将牌是2张牌
		if (SHUNZI.size() != 3 || KEZI.size() != 3)
			throw new RuntimeException();
		if (JIANG.size() != 2)
			throw new RuntimeException();

		if (aliveTiles.isEmpty())
			return emptyList();

		List<Tile> aliveTileList = new ArrayList<>(aliveTiles);

		// 解析出全部的preShunke
		Map<TileSuit, List<Tile>> candidatesBySuit = candidates.stream()
				.collect(groupingBy(tile -> tile.type().suit()));
		List<PreUnit> preShunkes = parsePreShunkes(aliveTileList, candidatesBySuit);

		// 按照从好到差排序（牌数越多越好，牌数相同的，lackedTypes种类越多越好）
		preShunkes.sort(Comparator.<PreUnit, Integer> comparing(preUnit -> preUnit.tiles.size())
				.thenComparing(preUnit -> preUnit.lackedTypesList.size()).reversed());

		// 找出与最差preShunke情况相同的units中的牌
		Set<Tile> remainTiles = new HashSet<>(aliveTiles);
		List<Tile> tilesFromWorstUnits = new ArrayList<>();
		@SuppressWarnings("unused")
		int crtUnitSize = Integer.MAX_VALUE, crtLackedKinds = Integer.MAX_VALUE;
		for (PreUnit shunke : preShunkes) {
			if (remainTiles.isEmpty())
				break;
			if (crtUnitSize > shunke.tiles.size()
			/*
			 * || (crtUnitSize == shunke.tiles.size() && crtLackedKinds >
			 * shunke.lackedTypesList.size())
			 */) {
				tilesFromWorstUnits.clear();
				crtUnitSize = shunke.tiles.size();
				crtLackedKinds = shunke.lackedTypesList.size();
			}
			shunke.tiles.stream().filter(remainTiles::contains).forEach(tile -> {
				tilesFromWorstUnits.add(tile);
				remainTiles.remove(tile);
			});
		}

		reverse(tilesFromWorstUnits);
		return tilesFromWorstUnits;
	}