Java卡牌游戏:修复有序添加卡牌与对子计数方法问题
修复卡牌游戏中
addCard和numPairs方法的问题 嘿,我来帮你搞定这两个方法的问题!咱们先拆解核心问题:一是直接访问Card类的私有字段rank导致的编译错误,二是两个方法的逻辑不符合需求。咱们一步步来修复:
核心问题:私有字段访问
Card类里的rank是私有成员,所以你在SimpleCardGame2类里直接写cards.get(x).rank.ordinal()会触发编译错误。咱们可以通过两种方式解决:要么给Card添加获取rank的公共方法,要么用Card已经实现的compareTo方法(更适合排序场景)。
1. 修复addCard方法
你原来的代码有三个明显问题:
- 循环条件写死
x<10,但cards列表一开始是空的,会直接抛出索引越界异常 - 直接访问私有
rank字段导致编译错误 - 逻辑错误:比如判断卡牌rank相等就直接return,这会阻止添加同rank的卡牌(但咱们需要添加来统计对子),而且插入位置的判断逻辑不对
修复后的addCard代码:
private static void addCard(ArrayList<Card> cards, Card c) { // 遍历列表,找到第一个比当前卡牌大的位置,插入到它前面 for (int x = 0; x < cards.size(); x++) { Card currentCard = cards.get(x); // 用Card类自带的compareTo方法比较顺序,既符合排序规则,又避免访问私有字段 if (currentCard.compareTo(c) > 0) { cards.add(x, c); return; } } // 如果所有卡牌都比当前卡牌小,就添加到列表末尾 cards.add(c); }
修复说明:
- 用
cards.size()代替固定的10,适配列表动态变化的长度,避免索引越界 - 利用
Card已经实现的compareTo方法判断卡牌顺序,完美契合你要的升序需求(先按rank升序,rank相同按suit升序) - 移除了错误的“相等就return”逻辑,允许添加同rank的卡牌
2. 修复numPairs方法
原来的双重循环逻辑会把三张同rank的卡牌统计成3次(比如三张A会被数成(A1,A2)、(A1,A3)、(A2,A3)三个组合),完全不符合“三张算1对、四张算2对”的规则,同时还存在私有字段访问错误。
第一步:给Card类添加公共方法获取rank
在Card类里添加以下代码,安全获取私有rank字段:
public Rank getRank() { return rank; }
第二步:重写numPairs方法
正确的思路是先统计每个rank出现的次数,再对每个次数计算可组成的对子数(次数//2,比如3次就是1对,4次就是2对),最后累加所有结果:
private static int numPairs(ArrayList<Card> cards) { // 初始化数组,统计每个rank的出现次数(Rank共有13种,所以数组长度为13) int[] rankCount = new int[Rank.values().length]; // 遍历所有卡牌,统计每个rank的次数 for (Card card : cards) { Rank currentRank = card.getRank(); rankCount[currentRank.ordinal()]++; } int totalPairs = 0; // 计算每个rank能贡献的对子数,累加得到总数 for (int count : rankCount) { totalPairs += count / 2; } return totalPairs; }
修复说明:
- 用数组统计rank出现次数,逻辑清晰且效率更高
- 用
count//2完美实现题目规则:3张→1对,4张→2对,2张→1对 - 通过公共方法
getRank()访问rank字段,避免私有访问错误
额外小修复
注意main方法里的deck.remove(rnd.nextInt(deck.size())-1):当deck.size()为1时,rnd.nextInt(1)返回1,减1后是0,刚好是合法索引,没问题。但如果MyRandom的nextInt逻辑有变动,建议确认索引范围始终在0到deck.size()-1之间。
修复后你的代码就能完美符合预期输出啦!
内容的提问来源于stack exchange,提问作者Kira
相关产品推荐
相关产品推荐

