【问题标题】:Not allowing the same player to be both players in a game不允许同一玩家同时成为游戏中的玩家
【发布时间】:2018-10-30 09:44:51
【问题描述】:

我正在制作一个 OOP 模型,玩家可以在其中加入游戏平台内的游戏。标准之一是不允许同一个人同时玩游戏,现在我被困在如何扩展这一点,因为有任意数量的最大玩家

在播放器类中..

公共类 GameExt2{

    private final int minAge;   
    private final PlayerExt2[] players;
    private String gameName;
    private int gameId;
    private double fee;
    private double amountOwed;
    private double totalFeesOwed;
    private int numberOfPlayersPlaying;
    private String playerNames;
    private int oweLimit;
    private int maxNumberPlayers;



public GameExt2( String gameName, int gameId, int minAge, double fee, int oweLimit, int maxNumberPlayers){



    this.gameId=gameId;
    this.gameName=gameName;
    this.minAge=minAge;
    this.fee=fee;
    this.oweLimit=oweLimit;
    this.players=new PlayerExt2[maxNumberPlayers];


    public String matchId(PlayerExt2 player){
        return("Sorry " + player.getName()+ ", you cannot be both players");
}





    public String isTooYoung(PlayerExt2 player){
        return("Sorry " + player.getName()+ ", you are too young to play" +gameName);
}





    public String maxPlayersReached(PlayerExt2 player){
        return("Sorry " + player.getName()+ ", there are already "+maxNumberPlayers+ " playing");
}





    private void playerJoined(PlayerExt2 player){
        System.out.println(player.getName() + " has joined the game " + gameName);          
    }






   public void addPlayer(PlayerExt2 player) {
        int nextFreeSlot = getNextFreeSlot();
        if (nextFreeSlot > 0) {
            if (isEligible(player)) {
                if (!isAlreadyPlaying(player)) {
                    players[nextFreeSlot] = player;
                    playerJoined(player);
                player.addGameJoined();
                player.addFeeOwed(fee);
                player.setNameGamePlaying(gameName);            //necessary for printing details of the player

                }
                else {
                    matchId(player);
                                                        // Already playing
                }
            }
            else {
              isTooYoung(player);
                                                        //player inelligible to play
            }
        }
        else {
            maxPlayersReached(player);
                                                            // game already full
        }
    }





    private boolean isAlreadyPlaying(PlayerExt2 newPlayer) {
        for (PlayerExt2 player : players) {
            if (player.getId() == newPlayer.getId()) return true;
        }
        return false;
    }





    private int getNextFreeSlot() {
        for (int i = 0; i < players.length; i++) {
            if (players[i] == null) return i;
        }
        return -1;                                          // negative indicates there's no free slot
    }





    private boolean isEligible(PlayerExt2 player) {
        return player.getAge() > minAge;
    }

Player class...




    public String addFeeOwed(double fee){

        amountOwed=amountOwed+fee;
        return("For playing this game of "+nameGamePlaying+ ", "+playerName+"'s balance now stands at £"+amountOwed);
}



    public void addGameJoined(){
        gamesJoined++;
}

主要部分...

    GameExt2 snakesAndLadders=new GameExt2("SnakesAndLadders",4564345,8,3,10,4);




    PlayerExt2 marina= new PlayerExt2(123, "Marina", 15, 4,1999,0);
    marina.calculateAge();
 System.out.println(marina.printDetails());
    snakesAndLadders.addPlayer(marina);



    PlayerExt2 erin=new PlayerExt2(163,"Erin",3,6,2010,0);
    erin.calculateAge();
System.out.println(erin.printDetails());
    snakesAndLadders.addPlayer(erin);




    PlayerExt2 matthew=new PlayerExt2(312,"Matthew",27,5,2002,12);
    matthew.calculateAge();
System.out.println(matthew.printDetails());
    snakesAndLadders.addPlayer(matthew);

【问题讨论】:

  • 如果playerId是唯一的,那不就是playerOne.playerId != playerTwo.playerId吗?
  • 为什么构造函数中有方法声明? (猜你格式不对)
  • @Andrew 我想它应该是两个相邻的方法:构造函数,然后是joinGame。我只是格式化了那里的内容-一团糟。
  • 我对您的代码应该如何构建进行了有根据的猜测。如果你学会了正确的缩进,你就不会有这个问题。
  • 是的!这会出现在条件语句中吗?(对不起,我是编程新手)

标签: java oop


【解决方案1】:

如果您认为这应该在概念上进行结构化,那么这些并不是玩家自己应该强制执行的约束。在现实生活中,玩家并不关心他们是否太年轻而不能玩。在锦标赛中,这将是某个管理员或裁判的责任。我们不必对此进行精确建模,但重点是它应该不在玩家的控制范围内。我会将这个逻辑放在 Game 类中,Players 会添加到该类中。

您已经可以看到这对您的代码产生了奇怪的影响。你的播放器有一个numberOfPlayers 字段。这有意义吗? numberOfPlayers 是一个人的财产吗?你的护照或驾照上有这些信息吗?

这是一个粗略的结构(不完整的代码)

class Game
{
    private final int minAge;
    private final Player[] players;

    public Game(int numberOfPlayers, int minAge) {
        //create array of the correct size, it will be filled with nulls
        this.players = new Player[numberOfPlayers];
        this.minAge = minAge;
    }

    void addPlayer(Player player) {
        int nextFreeSlot = getNextFreeSlot();
        if (nextFreeSlot > 0) {
            if (isEligible(player)) {
                if (!isAlreadyPlaying(player)) {
                    players[nextFreeSlot] = player;
                }
                else {
                    // Already playing
                }
            }
            else {
                // Ineligible
            }
        }
        else {
            // Full
        }
    }

    private boolean isAlreadyPlaying(Player newPlayer) {
        for (Player player : players) {
            if (player.getId() == newPlayer.getId()) return true;
        }
        return false;
    }

    private int getNextFreeSlot() {
        for (int i = 0; i < players.length; i++) {
            if (players[i] == null) return i;
        }
        return -1; // negative indicates there's no free slot
    }

    private boolean isEligible(Player player) {
        return player.getAge() > minAge;
    }
}

【讨论】:

  • 哦,哇,我感激不尽!这更有意义,我的思维方式不正确!非常感谢您抽出时间来帮助我!
  • 即使你只有两个玩家,我仍然会使用一个集合来“收集”所有玩家。这避免了if (playerOne == null) 的东西,并且在允许更多玩家时更容易适应。由于我们验证没有 id 重复,如果玩家不需要排序(例如当他们加入时),我们甚至可以使用 Set。
  • @Tom 我不确定我是否同意。显然,如果需要n 玩家,那么集合是解决它的唯一方法,但如果总是两个玩家,那么我怀疑如果只有两个字段,游戏中的其他方法会更容易阅读。在不知道游戏是什么的情况下很难知道,但这是我的怀疑。我可能会更进一步,有一个 GameSignUp 或其他东西(实际上是一个 GameFactory)来强制执行这些约束,然后可以保证游戏本身在实例化时有 2 个非空字段。
  • 我觉得我从你身上学到了很多东西!非常感谢(对不起,如果我听起来很重复!)
  • @MarinaCalder 没问题。乐于助人
【解决方案2】:

几点说明:

  • joinGame() 不应在 Player 类中。放置此方法是不可扩展的,但是从它提到的参数 nameGamePlaying 的事实来看,在 Player 中没有引用,这个方法已经在 Game.class 或任何你的等价物中。
  • 如果你想比较两个实例是否代表同一个对象,重写equals方法,因为Java中很多方法都用它来比较,这样做会省去很多麻烦。 equals 方法应该比较两个实例是否逻辑上等价,所以在这种情况下我们只需要比较 playerId,但是其他类可能需要其他比较字段。
  • 不要硬编码常量,比如最大玩家数。您的示例证明了这一点,因为您实际上最多需要 2 个玩家,但将值编码为 3。当您意识到这个错误,或者如果您只想增加最大玩家的数量,您将不得不追踪每个发生 3 并替换它。相反,在类级别声明一个常量 MAX_PLAYERS,并在必要时引用它。
  • 您需要在 Person.class 中声明 getter 才能使以下内容起作用。
  • 嵌套 if 语句以消除重复。如果您将后续逻辑嵌套在检查最大玩家数量的 if 语句中,则无需像最初那样不断检查最大玩家数量。

代码如下,有问题请追问。


//In Game.class or equivalent
private final int MAX_PLAYERS = 2;
private List<Player> playerList; //Should be initialised with the main Game(?) class.
public String joinGame(Person player){
    if(playerList.size() < MAX_PLAYERS){
        if(!playerList.contains(player) && player.getPlayerAge() >= minAge){
            playerList.add(player)
            return (player.getPlayerName() + " has joined the game " + nameGamePlaying + ".");
        }else{
            return ("Sorry, " + player.getPlayerName()+ " is too young to play or is already playing " + nameGamePlaying);
        }
    } else {
        return ("Sorry, "+ player.getPlayerName()+ " cannot play " + nameGamePlaying + " as there are already two players.");
    }
}

//In Person.class
@Override
public boolean equals(Object obj){
    if(this == obj){
        return true;
    }
    if(obj == null){
        return false;
    }
    if(getClass() != obj.getClass()){
        return false;
    }
    Person toCompare = (Person) obj;

    if(this.playerId != toCompare.getPlayerId()){
        return false;
    }

    //Optional, depending on your construct.
    if(playerName == null){
        if(toCompare.getPlayerName != null){
            return false;
        }
    }else{
        if(!playerName.equals(toCompare.getPlayerName(){
            return false;
        }
    }

    //... More logical equality checks

    return true;
}

【讨论】:

  • 非常感谢您!我已经完成了上面编辑的不太复杂的版本,但是它给了我奇怪的输出数字和消息,从你所看到的来看,我所写的内容有问题吗? @安德鲁
  • 需要更多信息,而不仅仅是“奇怪的输出数字和消息”才能告诉您更多信息。
  • 例如,当没有人玩时,它不会让玩家加入最多 4 人的游戏,输出“游戏已满”
  • 一方面,你的玩家数组有修饰符 final。查看 final 的作用,并查看如何调试您的程序以确定哪些会受到影响,哪些不会受到影响。
  • 我已经改成公开了,还是不让玩家加入
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多