java - 改进配对玩家的算法 - 重复代码过多

标签 java solid-principles code-duplication

我有球员。球员获得了优先位置。我们有 3 个位置 - 防守者、进攻者、两者(在两个位置上都擅长的球员)。 我需要创建两人团队。玩家配对应该是这样的: “攻击者会与防守者或能够胜任两个位置的人配对。当然,那些在两个位置上都感到舒服的人可以在一个团队中相互配合。两名后卫或两名攻击者比其他组合弱,所以应该仅当没有其他选择时才以这种方式配对。”

我写过这样的东西。我知道这是幼稚的实现,但找不到更好的方法来做到这一点。

首先,我按照球员的位置对他们进行排序,所以我有 3 个列表。然后,使用 while 循环,我首先处理攻击者,然后是防御者,然后是攻击者/防御者。

有什么办法可以改善吗?如果没有,我想知道如何将重复的代码提取到方法中。

package foostour.app;

import foostour.app.model.Player;
import foostour.app.model.Team;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

class TeamScheduler {

    private List<Team> teams = new ArrayList<>();

    private List<Player> defenders = new ArrayList<>();
    private List<Player> attackers = new ArrayList<>();
    private List<Player> attackersAndDefenders = new ArrayList<>();
    private int teamNumber = 0;

    List<Team> createTeams(List<Player> shuffledPlayers) {

        sortPlayersByPosition(shuffledPlayers);

        while (!attackers.isEmpty()) {
            Team team = new Team("Team " + (teamNumber + 1));
            team.setFirstPlayer(attackers.remove(new Random().nextInt(attackers.size())));
            if (!defenders.isEmpty()) {
                team.setSecondPlayer(defenders.remove(new Random().nextInt(defenders.size())));
            } else if (!attackersAndDefenders.isEmpty()) {
                team.setSecondPlayer(attackersAndDefenders.remove(new Random().nextInt(attackersAndDefenders.size())));
            } else if (!attackers.isEmpty())
                team.setSecondPlayer(attackers.remove(new Random().nextInt(attackers.size())));
            teams.add(team);
            teamNumber++;
        }


        while (!defenders.isEmpty()) {
            Team team = new Team("Team " + (teamNumber + 1));
            team.setFirstPlayer(defenders.remove(new Random().nextInt(defenders.size())));
            if (!attackers.isEmpty()) {
                team.setSecondPlayer(attackers.remove(new Random().nextInt(attackers.size())));
            } else if (!attackersAndDefenders.isEmpty()) {
                team.setSecondPlayer(attackersAndDefenders.remove(new Random().nextInt(attackersAndDefenders.size())));
            } else if (!defenders.isEmpty())
                team.setSecondPlayer(defenders.remove(new Random().nextInt(defenders.size())));
            teams.add(team);
            teamNumber++;
        }


        while (!attackersAndDefenders.isEmpty()) {
            Team team = new Team("Team " + (teamNumber + 1));
            team.setFirstPlayer(attackersAndDefenders.remove(new Random().nextInt(attackersAndDefenders.size())));
            if (!attackers.isEmpty()) {
                team.setSecondPlayer(attackers.remove(new Random().nextInt(attackers.size())));
            } else if (!defenders.isEmpty()) {
                team.setSecondPlayer(defenders.remove(new Random().nextInt(defenders.size())));
            } else if (!attackersAndDefenders.isEmpty()) {
                team.setSecondPlayer(attackersAndDefenders.remove(new Random().nextInt(attackersAndDefenders.size())));
            }
            teams.add(team);
            teamNumber++;
        }

        return teams;
    }

    private void sortPlayersByPosition(List<Player> players) {
        for (Player player : players) {
            if (player.getPreferredPosition() == PositionType.BOTH)
                attackersAndDefenders.add(player);
            else if (player.getPreferredPosition() == PositionType.ATTACK)
                attackers.add(player);
            else if (player.getPreferredPosition() == PositionType.DEFENSE)
                defenders.add(player);
        }
    }
}

最佳答案

您可以将三个 for 循环简化为一个 for 循环。为了做到这一点,你最终会在 for 循环内部得到更多的内容。您还必须更改 for 循环中的条件才能检查所有三个列表。

while (!both.isEmpty() || !attackers.isEmpty() || !defenders.isEmpty()) {
    if (!attackers.isEmpty()) {
        team.setFirstPlayer(attackers.remove(new Random().nextInt(attackers.size())));
    } else if (!both.isEmpty()) {
        team.setFirstPlayer(both.remove(new Random().nextInt(attackers.size())));
    } else if (!defenders.isEmpty()) {
        team.setFirstPlayer(defenders.remove(new Random().nextInt(attackers.size())));
    }

    if (!defenders.isEmpty()) {
        team.setFirstPlayer(defenders.remove(new Random().nextInt(attackers.size())));
    } else if (!both.isEmpty()) {
        team.setFirstPlayer(both.remove(new Random().nextInt(attackers.size())));
    } else if (!attackers.isEmpty()) {
        team.setFirstPlayer(attackers.remove(new Random().nextInt(attackers.size())));
    }
}

这将首先检查攻击者并将他们放入团队中。如果没有攻击者,就会派出一个可以同时完成这两件事的人。第二组 if 语句将防守者置于第二位置,或者将防守者置于该位置上。只有在攻击者或防御者明显多于对方的情况下,才会将两个防御者或两个攻击者放在同一团队中。

关于java - 改进配对玩家的算法 - 重复代码过多,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58476058/

相关文章:

java - 使用此方法时遇到一些问题

java - 使用 java websocket API 和 Javascript 上传文件

java - 实现空对象模式的方法

c# - 教程逻辑与主应用程序逻辑分离

c# - S.O.L.I.D 原理和编译?

Java,在任何方向循环遍历二维数组

java - 模拟器在输入经纬度时重新启动

dependency-injection - 依赖注入(inject)能走多远?

perl - 如何在 Perl 中找到复制/粘贴(复制、克隆)代码?

iOS 在现有应用程序的基础上构建应用程序扩展。如何避免代码重复?