【问题标题】:Can I use a caught exception to move in a circle around an array?我可以使用捕获的异常在数组周围移动吗?
【发布时间】:2012-03-08 15:13:30
【问题描述】:

我正在编写一个围绕玩家圈子进行的纸牌游戏(就像大多数纸牌游戏一样)。播放可以向左或向右进行,并分配给布尔值。正确播放右侧,错误播放左侧。我将所有播放器对象都放在一个数组列表中,因此当我需要找到下一个将要播放的播放器时,我会获取当前播放器并将下一个播放器分配为列表中的下一个播放器。如果当前玩家是列表中的最后一个玩家,尽管我会得到一个异常说超出界限......除非我发现异常并将下一个玩家指定为列表中的第一个玩家。这是一种好的方法吗?我对如何在一个圆圈中绕过一个列表没有其他想法。谢谢。

   public AbstractPlayergetNextPlayerToPlay(AbstractPlayer currentPlayer,             
   ArrayList<AbstractPlayer> players, boolean directionOfPlay){

    AbstractPlayer nextPlayerToPlay = null;

    //if the direction of play is forwards (true)
    if(directionOfPlay){
        for(int i=0;i<players.size();i++){
            try{
            if(players.get(i).equals(currentPlayer)){
                nextPlayerToPlay = players.get(i+1);
            }
            }catch(ArrayIndexOutOfBoundsException e){
                nextPlayerToPlay = players.get(0);//first player in the list
            }
        }
    }
    else{
        //if the direction of play is backwards (false)
        for(int i=players.size();i>0;i--){
            try{
            if(players.get(i).equals(currentPlayer)){
                nextPlayerToPlay = players.get(i-1);
            }
            }catch(ArrayIndexOutOfBoundsException e){
                nextPlayerToPlay = players.get(players.size());//last player in list  T
            }
        }
    }

    return nextPlayerToPlay;

}

【问题讨论】:

  • 使用取模运算符,例如。 (i + 1) % player.size()
  • 当使用逻辑是一种选择时,我永远不会捕获异常。

标签: java exception arraylist


【解决方案1】:

试试这个,应该同时处理前后

int currentPlayerIndex = players.indexOf(currentPlayer);
int nextPlayerIndex = currentPlayerIndex + (direction0fPlay ? 1 : -1);

// Ensure index is in array
nextPlayerIndex = (nextPlayerIndex + players.size()) % players.size();

return players.get(nextPlayerIndex);

【讨论】:

  • 我会在之前给出那个,我从来没有想过模数运算符!谢谢你和其他回复的人。
【解决方案2】:

两件事,
一个:

for(int i=players.size();i>0;i--){

当你做players.get(i)时,forst迭代期间肯定会产生一个异常,当你反向迭代时:你应该从players.size()-1开始。你也可能想迭代i&gt;=0,[但你又倾向于get(-1)]

两个: 异常[相对]很慢,尽管有可能 - 通常建议使用逻辑运算来避免这种行为。
您可以改用i % size [缓存int size = players.size() before iteration],注意它不适用于get(-1),您将不得不在那里做一些[很少]额外的工作。例如,get((i+1+size) % size)get((i-1+size) % size)-size &lt; i &lt; size 时将始终有效

【讨论】:

    【解决方案3】:

    你为什么不试试

    int playerIndex = 0;
    while(true) {
        playerIndex++;
        if (playerIndex == players.size()) {
            playerIndex = 0;
        }
    
        [do your stuff with the player here]
    
    }
    

    通过这种方式,您可以递增播放器索引,直到到达数组的末尾。然后将索引重置为 0。

    【讨论】:

      【解决方案4】:

      我建议查看链接列表是否适合您的需求。专门阅读循环链表和双向链表。 http://en.wikipedia.org/wiki/Linked_list

      本质上,链表以给定的顺序跟踪一组项目。你从头节点开始,头节点指向next,指向next,指向next,等等

      在循环链表中,最后一个节点指向完成循环的第一个节点。在双向链表中,节点指向前一个节点以及下一个节点。这解决了倒车以及处理列表中最后一个玩家的问题。

      通常,链表会因为花费很长时间来搜索特定节点而受到抨击,但您可以通过将头节点的引用更新为始终是当前玩家而不是静态起点来提高效率,或符合您游戏逻辑的类似内容。

      【讨论】:

        【解决方案5】:

        改变这个

        nextPlayerToPlay = players.get(i+1);
        

        到这里

        nextPlayerToPlay = players.get((i+1) % players.size());
        

        当到达最后一个玩家时,这会将索引返回到 0,并且比抛出和捕获异常更高效和优雅。

        你可以为另一个方向做类似的事情。

        【讨论】:

        • 向后迭代失败,0-1 % 7 == -1
        【解决方案6】:

        对于上限,模块运算符%是你的朋友。

        nextPlayerToPlay = players.get((i+1)%players.size()); 
        

        (您可能希望将 player.size() 缓存在变量中)

        对于下限,查值有那么难吗?

        nextPlayerToPlay = players.get(i > 0 ? players.get(i-1): players.get(players.size()-1)); 
        

        【讨论】:

          【解决方案7】:

          使用模数运算符,例如。 (i + 1 + player.size()) % player.size()

          所以如果你有 6 个玩家:

          (6 + 1 + 7) % 7 = 0
          

          这将回到第一个玩家

          【讨论】:

          • 向后迭代失败,0-1 % 7 == -1
          • 抱歉忘记 Java 没有真正的模数运算符 - 现已修复
          【解决方案8】:

          您可以在连接成一个圆圈的双向节点集上表示玩家的圆圈,然后根据方向简单地询问节点(代表玩家)是否有下一个玩家。您可以同时避免异常处理和演算。

          【讨论】:

            猜你喜欢
            • 2017-06-24
            • 2021-08-25
            • 1970-01-01
            • 1970-01-01
            • 2013-01-09
            • 1970-01-01
            • 2017-01-04
            • 2019-09-30
            • 1970-01-01
            相关资源
            最近更新 更多