Uno游戏playCard方法中如何判断数字卡牌与弃牌堆匹配?
Uno游戏playCard方法实现方案
核心问题
开发Uno游戏时,playCard(Card card)方法仅接收Card类型参数,需判断打出的NumberCard数字是否与弃牌堆顶卡牌匹配,是否需要类型转换及具体操作方式。
解决方案
是否需要类型转换?
需要。Card是抽象父类,仅包含颜色属性,没有数字属性;NumberCard作为子类才拥有数字属性。要获取数字并比较,必须先判断卡牌类型,再进行安全类型转换。
具体操作步骤
- 获取弃牌堆顶卡牌:通过
getLatestDiscard()拿到当前弃牌堆的最后一张牌 - 类型判断:分别判断要打出的卡牌和堆顶卡牌是否为
NumberCard实例 - 安全转换与数字比较:若两者都是数字牌,转换为
NumberCard后比较数字;同时保留颜色匹配的判断逻辑(符合Uno出牌规则:颜色相同或数字相同即可出牌) - 扩展其他卡牌规则:比如功能牌(SkipCard、HitCard)或万能牌,可额外判断功能匹配或万能牌逻辑
修改后的playCard方法代码
public void playCard(Card card) { Card latestDiscard = getLatestDiscard(); boolean canPlay = false; // 颜色匹配(所有卡牌通用规则) if (card.getColor() == latestDiscard.getColor()) { canPlay = true; } // 数字匹配(仅当两张都是NumberCard时生效) else if (card instanceof NumberCard && latestDiscard instanceof NumberCard) { NumberCard playedNumberCard = (NumberCard) card; NumberCard discardNumberCard = (NumberCard) latestDiscard; if (playedNumberCard.getNumber() == discardNumberCard.getNumber()) { canPlay = true; } } // 可扩展:功能牌匹配(如SkipCard与SkipCard匹配)、万能牌逻辑等 if (canPlay) { // 执行出牌逻辑:移除玩家手牌、加入弃牌堆、更新状态 players.get(0).getHand().remove(card); discardPile.add(card); playedCard = true; currentDrawn = 0; // 出牌后重置抽牌次数 } else { System.out.println("该卡牌无法打出,请选择合法卡牌!"); } }
额外优化建议
- 安全类型判断:始终用
instanceof先判断类型再转换,避免ClassCastException - 多态优化出牌规则:在Card抽象类中添加抽象方法
canPlayOn(Card other),让子类实现各自的出牌逻辑,简化playCard方法:
// 在Card抽象类中添加 public abstract boolean canPlayOn(Card other); // NumberCard类中实现 @Override public boolean canPlayOn(Card other) { if (this.getColor() == other.getColor()) return true; return other instanceof NumberCard && this.getNumber() == ((NumberCard) other).getNumber(); } // SkipCard类中实现 @Override public boolean canPlayOn(Card other) { if (this.getColor() == other.getColor()) return true; return other instanceof SkipCard; } // 简化后的playCard方法 public void playCard(Card card) { Card latestDiscard = getLatestDiscard(); if (card.canPlayOn(latestDiscard)) { players.get(0).getHand().remove(card); discardPile.add(card); playedCard = true; currentDrawn = 0; } else { System.out.println("该卡牌无法打出,请选择合法卡牌!"); } }
- 修复代码小问题:
buildDeck()中x == 3的判断可改为else(IDE提示是因为前面的x==0/1/2已覆盖所有x<=3的其他情况);endTurn()中的重复逻辑可合并。
内容的提问来源于stack exchange,提问作者Dodobird108
相关产品推荐
相关产品推荐

