【问题标题】:UNO card game remove card from handUNO纸牌游戏从手上移除卡片
【发布时间】:2012-04-30 02:25:37
【问题描述】:

尝试用java创建纸牌游戏“UNO”。当玩家打出一张牌时,应将其从手中移走,而其他元素则向左移动。它以一个 int n 作为参数,它指的是被丢弃的卡片。该方法应该更改我指定为类字段的卡片数组。它是一组对象,即卡片或玩家手牌。运行时,它会产生一个 nullPointerException。我知道为什么会发生错误,我只是不知道如何解决它。我也试图避免使用数组列表。它还会返回被丢弃的卡片,以便打印。谢谢。

public Card removeCardFromHand(int n)
{
    Card c = cards[n];
    Card[] tempCards = new Card[cards.length - 1];
    for(int i = 0; i < n; i++)
    {
        tempCards[i] = cards[i];
    }
    for(int i = n; i < cards.length; i--)
    {
        tempCards[n] = cards[n + 1];
    }
    cards = tempCards;
    return c;
} 

错误代码:

java.lang.ArrayIndexOutOfBoundsException: 7

at Player.removeCardFromHand(Player.java:86)
at BUno.executeOnePlay(BUno.java:112)
at BUno.play(BUno.java:70)
at BUno.main(BUno.java:186)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at edu.rice.cs.drjava.model.compiler.JavacCompiler.runCommand(JavacCompiler.java:271)

发生这种情况是因为在这种情况下,玩家有 7 张牌。当第 7 个被删除时,第 7 个索引为空。当玩家必须抽一张牌时,我写了一个类似的方法来添加一张牌,它完美无缺。我正在为即将到来的考试练习,它不包括数组列表或向量,所以对我来说没有用。

【问题讨论】:

  • 你为什么不想使用ArrayList“我知道为什么会发生错误” 请分享。另外,请粘贴异常的整个堆栈跟踪。
  • 为什么不用矢量,它可以改变大小?
  • 'ArrayList' 存在的主要原因是为了处理这类问题。但你可能有理由不使用它!此外,我认为您在第二个 for 循环中应该是 'i++' (从 n 到cards.length)。
  • @stark 见this

标签: java arrays playing-cards indexoutofboundsexception


【解决方案1】:
for(int i = n; i < cards.length; i--)
{
    tempCards[n] = cards[n + 1];
}

那是什么? :-)

三个直接的问题。第一个是您在循环内的数组索引中使用n,而不是正确的i

第二个是,即使你修复了这个问题,你也会超出数组的末尾。

第三个是你应该增加i 而不是减少它。减少它意味着循环将永远运行,因为i 将始终小于cards.length。而且,永远,我的意思是直到你开始尝试用cards[-1]做某事的地步:-)

相反,您应该尝试:

for (int i = n; i < cards.length - 1; i++)
    tempCards[i] = cards[i + 1];

【讨论】:

  • 你不觉得应该是i++吗? (n
  • 这个循环是将剩余的不会被移除的卡片添加到较短的 tempCards 数组中。不过我会试试你的方法
  • @AlexMoss,抱歉,这是一个反问。我很清楚那是什么。我对 “那是什么?” 的评论应该带着怀疑的表情来阅读,就像 “你写这个时到底在想什么?”。 :-)
  • 没有问题,@AlexMoss - 您可能想研究使用数据结构的可能性,该数据结构可以让您就地更改牌组,而不必创建品牌新数组。但这可能是另一个问题的最佳选择。
【解决方案2】:

您的第二个 for 循环没有按照您的预期进行。您只是一遍又一遍地重新分配tempCards[n] = cards[n+1],同时不断减少i

for(int i = n; i < cards.length; i--) 
    { 
        tempCards[n] = cards[n + 1]; 
    } 

对于一个例子来说,i 以类似 3 的值开始,这将小于cards.length 然后你将i 递减为 2、1、0、-1、-2 等等.

【讨论】:

    【解决方案3】:

    您可以使用LinkedList 而不是依赖数组。将物品 (Card) 移除和添加到玩家手中会更快。

    我发现您发布的代码存在两个问题。第一个是潜在的并发访问(但您可能会在更高级别处理它):是否可以同时在一张卡的移除未完全完成时添加一张卡?

    第二个在这里:

    for(int i = n; i < cards.length; i--) 
    { 
       tempCards[n] = cards[n + 1]; 
    }
    

    您应该在另一个方向进行复制 (i++) 否则您的 tempCard 将包含类似 {Card1, Card2, ..., Card n-1, Card n+1, Card n, Card n -1 ... Card 2, Card 1} 或如果您尝试删除索引 > card.lengh / 2 的卡,则会因 ArrayIndexOutOfBound 崩溃

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-07-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-17
      相关资源
      最近更新 更多