洗牌
此操作包含的基本功能有:
- 组牌:组建 52 张扑克牌
- 四种花色:“♥️”,“♠️”,“⬛️”,“♣️”
- 每种花色 13 张牌:1~13
- 洗牌:将 52 张扑克牌打乱顺序
- 发牌:给三个人每人发 5 张牌
扩展功能:
- 清牌:将每人手中牌按照面值进行从大到小排序
Card 类
在此类中,我们将完成对每一张牌的构造
-
类中含有成员变量
- 花色:
suit
- 面值:
rank
- 花色:
-
带有一个含参的构造方法,用来之后传入对应参数进行新牌的构造
-
重写
toString()
方法,让输出的结果更美观
public class Card {public int rank;public String suit;public Card(int rank, String suit) {this.rank = rank;this.suit = suit;}@Overridepublic String toString() {return "{" ++ rank +" " + suit +"}";}
}
CardBox 类
所有的功能都将在这个类中进行具体地实现
组牌
组建 52 张牌:
List<Card> buildCard()
思路
- 创建一个容量为
52
,接收对象为Card
的链表cardList
- 两个 for 循环,为
Card
类里面的两个成员变量造值 - 随后依次为
Card
类实例化对象,将两个成员变量传入 Card 的构造方法中,创造出一张牌 - 最后依次将实例化出来的对象加入链表
代码
public class CardBox {public static final String[] suits = {"♥️", "♠️", "⬛️", "♣️"};public static List<Card> makeCard() {List<Card> cardList = new ArrayList<>(52);for (int i = 0; i < 4; i++) {for (int j = 1; j <= 13; j++) {int rank = j;String suit = suits[i];Card card = new Card(rank, suit);cardList.add(card);}}return cardList;}
}
洗牌
运用下标交换进行牌的打乱:
void shuffle(List<Card> cardList)
思路
- 使用随机数函数
Random
进行下标交换匹配,用随机数函数创造一个范围内的下标randomIndex
- 再让随机数
randomIndex
下标在顺序表中对应的牌与目标牌进行交换 - 交换需要用到一个自定义函数:
void swap(List<Card> cardList, int i, int j)
- 此函数对
cardList
链表进行操作,将其中i
位置的数据与j
位置的数据进行交换
- 此函数对
代码
public static void shuffle(List<Card> cardList) {for (int i = cardList.size() - 1; i > 0; i--) {int randomIndex = new Random().nextInt(i);swap(cardList,randomIndex,i);}
}private static void swap(List<Card> cardList, int i, int j){Card tmp = cardList.get(i);cardList.set(i,cardList.get(j));cardList.set(j,tmp);
}
发牌
将牌分发给三个人:
void drawCard (List<Card> cardList)
思路
- 为四个人创建三个
Card
类型的链表,就相当于是“他们的手
”,用来拿他们发到的牌 - 再创建一个以“
他们的手
”为类型的链表,就相当于是“发牌人的手
”,用来将发好的牌堆发给他们 - 发牌的原理是依次移走下标为
0
的那张牌
代码
public void drawCard (List<Card> cardList) {List<Card> hand1 = new ArrayList<>();List<Card> hand2 = new ArrayList<>();List<Card> hand3 = new ArrayList<>();List<List<Card>> hands = new ArrayList<>();hands.add(hand1);hands.add(hand2);hands.add(hand3);for (int i = 0; i < 5; i++) {for (int j = 0; j < 3; j++) {hands.get(j).add(cardList.remove(0));}}
}
扩展:清牌
在发牌之后,将每人手中牌按照面值进行从大到小排序:
思路
- 重写 Collection 接口中的
sort()
方法 - 在参数中直接传入一个用来排序链表的比较器
代码
public void drawCard (List<Card> cardList){List<Card> hand1 = new ArrayList<>();List<Card> hand2 = new ArrayList<>();List<Card> hand3 = new ArrayList<>();List<List<Card>> hands = new ArrayList<>();hands.add(hand1);hands.add(hand2);hands.add(hand3);for (int i = 0; i < 5; i++) {for (int j = 0; j < 3; j++) {hands.get(j).add(cardList.remove(0));}}for (int i = 0; i < 3; i++) {Collections.sort(hands.get(i), new Comparator<Card>() {@Overridepublic int compare(Card o1, Card o2) {return o1.rank - o2.rank;}});}System.out.println("第一个人的牌"+hand1);System.out.println("第二个人的牌"+hand2);System.out.println("第三个人的牌"+hand3);
}
运行结果
杨辉三角
思路
- 首位:每行的第一个都是
1
,直接add(1)
进入当前行curRow
- 中间的值:
- 第
i
行的第j
下标元素是第i - 1
行的第j
下标元素和j - 1
下标元素相加之和
- 第
- 末位:为
1
,直接add(1)
进入当前行curRow
代码
public List<List<Integer>> generate(int numRows) {List<List<Integer>> ret = new ArrayList<>();List<Integer> list = new ArrayList<>();//第一行第一列list.add(1);ret.add(list);for (int i = 1; i < numRows; i++) {//当前行List<Integer> curRow = new ArrayList<>();//首位均为 1curRow.add(1);//中间的for (int j = 1; j < i; j++) {//i = 1是当前行,那 i - 1就是上一行List<Integer> preRow = ret.get(i - 1);int x1 = preRow.get(j);int x2 = preRow.get(j - 1);curRow.add(x1 + x2);}//当前行,最后一个 1curRow.add(1);ret.add(curRow);}return ret;}