如何在控制台并排打印扑克牌?——Crazy Eights项目技术求助
解决控制台并排打印扑克牌 & 关于Deck继承ArrayList的疑问
嘿,我来帮你搞定这两个问题!
一、让扑克牌在控制台并排打印
你现在的问题是每张卡片的face()方法返回的是完整的多行字符串,直接打印会让卡片上下堆叠。要实现并排,我们需要逐行打印多张卡片的对应行,而不是打印完一张再打印另一张。
步骤1:修改Card类,返回卡片的行数组
把原来的face()方法改成返回一个字符串数组,每个元素对应卡片的一行:
class Card { private int value = 0; private String suit = null; public Card(int value, String suit) { this.value = value; this.suit = suit; } int getValue() { return value; } String getSuit() { return suit; } // 返回卡片的每一行字符串 String[] getFaceLines() { String[] lines = new String[8]; // 卡片总共8行:顶边框+6行内容+底边框 lines[0] = "+-----------+"; for(int lineIdx = 1; lineIdx <= 6; lineIdx++) { StringBuilder lineContent = new StringBuilder("|"); if(lineIdx == 2) { // 第二行显示牌面数值(优化显示A/J/Q/K) String displayValue = switch(value) { case 1 -> "A"; case 11 -> "J"; case 12 -> "Q"; case 13 -> "K"; default -> String.valueOf(value); }; // 对齐显示:两位数字(如10)占3位,一位数字前面补空格 lineContent.append(String.format("%3s", displayValue)).append(" "); } else if(lineIdx == 4) { // 第四行显示花色 String suitText = switch(suit) { case "Clubs" -> "CLUBS"; case "Diamonds" -> "DIAMONDS"; case "Hearts" -> "HEARTS"; case "Spades" -> "SPADES"; default -> ""; }; // 补空格保证每行内容长度一致 lineContent.append(" ").append(suitText).append(" ".repeat(9 - suitText.length())); } else { // 空行填充11个空格 lineContent.append(" "); } lineContent.append("|"); lines[lineIdx] = lineContent.toString(); } lines[7] = "+-----------+"; return lines; } }
步骤2:修改Deck类,逐行拼接打印多张卡片
在shuffle()方法中,获取多张卡片的行数组,然后逐行拼接打印:
class Deck extends ArrayList<Card> { private String[] suits = {"Clubs", "Diamonds", "Hearts", "Spades"}; private String[] ranks = {"2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "1"}; public Deck() { for (int i = 0; i < ranks.length; i++) { for (int j = 0; j < suits.length; j++) { this.add(new Card(Integer.parseInt(ranks[i]), suits[j])); } } } void shuffle() { Random random = new Random(); for (int i = 0; i < 52 - 1; i++) { int randomValue = i + random.nextInt(52 - i); Card card = this.get(i); this.set(i, this.get(randomValue)); this.set(randomValue, card); } // 打印两张并排的卡片 Card card1 = this.get(0); Card card2 = this.get(1); String[] card1Lines = card1.getFaceLines(); String[] card2Lines = card2.getFaceLines(); // 逐行拼接两张卡片的对应行 for(int i = 0; i < card1Lines.length; i++) { System.out.println(card1Lines[i] + " " + card2Lines[i]); } } }
这样打印出来的效果就会是两张卡片并排啦:
+-----------+ +-----------+ | A | | 10 | | | | | | CLUBS | | SPADES | | | | | | | | | | | | | +-----------+ +-----------+
二、关于Deck继承ArrayList的疑问
其实在实际开发中,更推荐用组合而非继承——也就是Deck类里定义一个private ArrayList<Card> cards;成员变量,然后封装add、get等方法,而不是直接继承ArrayList。
不过你的老师要求继承,大概率是为了简化高中阶段的学习:
- 继承后,Deck直接拥有ArrayList的所有方法(比如
add()、get()、set()),不用你自己再写封装代码 - 可以让你更专注于Deck的核心逻辑(初始化52张牌、洗牌),而不是集合操作的细节
但要明白:这种设计在专业项目中并不合适,因为Deck本质上"不是"ArrayList的一种,继承会暴露很多不必要的方法(比如clear()),违反了面向对象的里氏替换原则。不过作为高中项目,按老师的要求做就好啦~
内容的提问来源于stack exchange,提问作者Bert Hanz
相关产品推荐
相关产品推荐

